caddy-security icon indicating copy to clipboard operation
caddy-security copied to clipboard

question: access rest api behind auth

Open axi92 opened this issue 2 years ago • 15 comments

A clear and concise description of what you want to accomplish.

I got an application with an rest endpoint. I can login through the ui and access the app. But I have not managed to do this via curl. We use keycloak as the oauth plugin. With keycloak there are different tokens id and access token and I have not managed to get the right calls to get through the auth portal.

axi92 avatar May 17 '22 10:05 axi92

@axi92 , please provide your config and specify which route handles the rest endpoint.

greenpau avatar May 17 '22 11:05 greenpau

The endpoint would be https://releases.evva.link/sfw-releases/

And the config:

{
	debug

	order authenticate before respond
	order authorize before basicauth

	security {
		oauth identity provider keycloak {
			driver generic
			realm keycloak
			client_id {env.KEYCLOAK_CLIENT_ID}
			client_secret {env.KEYCLOAK_CLIENT_SECRET}
			scopes openid email profile
			metadata_url https://keycloak.evva.com/auth/realms/master/.well-known/openid-configuration
		}

		authentication portal myportal {
			crypto default token lifetime 3600
			crypto key sign-verify {env.JWT_SHARED_KEY}
			enable identity provider keycloak
			cookie domain evva.link
			ui {
				links {
					"releases" https://releases.evva.link icon "las la-link"
					"My Identity" "/whoami" icon "las la-user"
				}
			}
			transform user {
				match origin keycloak
				action add role authp/user
			}
		}

		authorization policy mypolicy {
			set auth url https://auth.evva.link/
			allow roles authp/admin authp/user
			crypto key verify {env.JWT_SHARED_KEY}
		}
	}
}



releases.evva.link {
	authorize with mypolicy
	reverse_proxy http://10.64.192.146:8888
	import letls
}

axi92 avatar May 17 '22 12:05 axi92

@axi92 , when you curl to your API, you would need providing the token acquired via authentication portal. What is the curl command you are using?

greenpau avatar May 17 '22 12:05 greenpau

Yes the problem is how do I get the token from the auth portal? I used this

export TKN=$(curl -X POST 'https://keycloak.evva.com/auth/realms/master/protocol/openid-connect/token' \
 -H "Content-Type: application/x-www-form-urlencoded" \
 -d 'username=USERNAME' \
 -d 'password=PASSWORD' \
 -d 'grant_type=password' \
 -d 'client_id=caddy-security-portal' | jq -r '.access_token')

axi92 avatar May 17 '22 12:05 axi92

Yes the problem is how do I get the token from the auth portal?

@axi92 , you do it like this https://authp.github.io/docs/authenticate/misc#authenticate

greenpau avatar May 17 '22 13:05 greenpau

@axi92 , please search the docs on how to enable accepting bearer token.

Once you authenticate to the portal and get the token, you pass that token in “ -H 'Authorization: Bearer: eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2Mzg3MzgyMjEsImp0aSI6IlN6d2JiOXI5eG5NeVlHUE5IbGZHeklQVlc5VHVLY1VlcndMbmNHR1BtIiwiaWF0IjoxNjM4NzM0NjIxLCJpc3MiOiJodHRwczovL2F1dGgubXlmaW9zZ2F0ZXdheS5jb206ODQ0My9sb2dpbiIsIm5iZiI6MTYzODczNDU2MTAwMCwic3ViIjoid2ViYWRtaW4iLCJlbWFpbCI6IndlYmFkbWluQGxvY2FsZG9tYWluLmxvY2FsIiwicm9sZXMiOlsiYXV0aHAvYWRtaW4iLCJhdXRocC91c2VyIl0sIm9yaWdpbiI6ImxvY2FsIiwiYWRkciI6IjEwLjAuMi4yIn0.QuSld2zKYtQX5gPIUlg7glRb7GXuieXm7ALxBTRd2dxCK4T-cZN-2KiK376Z1sxSFf3P3PA-ycrcazjdU5XETQ' “ header when making calls to your API.

greenpau avatar May 17 '22 13:05 greenpau

@axi92 , wait … the things I mentioned would not work with OAuth. Let me think and I will let you know how to go about it.

greenpau avatar May 17 '22 13:05 greenpau

@axi92 , 😄 I might know how to do it! 😆 ...

So ... I decided adding a feature that would take the id_token or access_token received from OAuth2.0 provider (e.g. Keycloak) and create a new cookie (AUTHP_IDP_ACCESS_TOKEN or AUTHP_IDP_ID_TOKEN) which would hold the tokens.

The new cookie will be next to the existing access_token and AUTHP_SESSION_ID issued by the portal.

image


Then, there are 2 options to handle this.

  1. Create /whoami/id_token which would return the id_token. You apps can then use the extracted token when accessing API
  2. Configured you apps to access AUTHP_IDP_ID_TOKEN

Does the above make sense?

greenpau avatar May 23 '22 01:05 greenpau

@axi92 , I am ready to get back to this. The gist is that I will be taking id_token sent by OAuth provider and injecting it into a cookie accessible only by the auth portal. Please see https://github.com/authp/authp.github.io/issues/28

Then, I will be able to retrieve it from SPA using the following URL parameters, e.g. https://auth.myfiosgateway.com:8443/whoami?format=json&id_token=true. The reply would contain JSON document with id_token field populated with the token received from OAuth provider.

Tested it with AWS Cognito and it works. My guess is that it would work with keycloak too.

greenpau avatar Jun 03 '22 02:06 greenpau

Sorry to revive this topic, but I'm in a similar situation here, and can't seem to understand exacly how to use the feature described in https://github.com/authp/authp.github.io/issues/28

The briefly elaborate what I want to do:

My config is pretty basic, as described in the docs:

{
	order authenticate before respond
	order authorize before basicauth

	security {
		oauth identity provider google {
			realm google
			driver google
			client_id XX
			client_secret XX
			scopes openid email profile
			enable id_token cookie
		}


		authentication portal myportal-xx.com {
			crypto default token lifetime 3600
			crypto key sign-verify {env.JWT_SHARED_KEY}
			enable identity provider google
			cookie domain xx.com

			transform user {
				match realm google
				action add role authp/user
			}

			transform user {
				match realm google
				match email [email protected]
				action add role authp/admin
			}
		}

		authorization policy mypolicy-xx.com {
			set auth url https://auth.xx.com/oauth2/google/authorization-code-callback
			crypto key verify {env.JWT_SHARED_KEY}
			allow roles authp/admin authp/user
			validate bearer header
			inject headers with claims
		}

}

auth.xx.com {
	authenticate with myportal-xx.com
}

xx.com {
    authorize with mypolicy-xx.com

    file_server * {
        root /web-data/
    }
    log {
        format console
    }
}

The auth is working fine, but now I would like to programmatically find a way to curl some pages behind this auth. for example:

curl -X GET -H 'Accept: application/json' -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" https://xx.com/overview.json

I assumed I could use use the access token generated via gcloud auth print-access-token for this, but as you described above, I can't use this procedure with OAuth, and can't seem to understand how should I adjust my curl command to get my access_token from google to work with this feature in https://github.com/authp/authp.github.io/issues/28. Can you help me out?

lucasbaile avatar Oct 17 '22 16:10 lucasbaile

I assumed I could use use the access token generated via gcloud auth print-access-token for this, but as you described above

@lucasbaile , at the moment this feature only works with local identity store.

curl -X GET -H 'Accept: application/json' -H 'Content-Type: application/json' -H "Authorization: Bearer $TOKEN" https://xx.com/overview.json

The $TOKEN should be the token issued by auth portal. It should work.

greenpau avatar Oct 17 '22 16:10 greenpau

@lucasbaile , also, you issue is slightly different from the one originally asked here. It is best if you open a new issue.

greenpau avatar Oct 17 '22 16:10 greenpau

I understand, sorry for the confusion!

Just opened a new issue on that matter 👍

lucasbaile avatar Oct 17 '22 17:10 lucasbaile

hi the link to the issue below is currently broken. is there another link for the same information? thank you for this useful project.

https://github.com/authp/authp.github.io/issues/28

mgmorcos avatar Mar 09 '24 02:03 mgmorcos

@mgmorcos , look for the issue in authcrunch/authcrunc.github.io repo. I recently migrated it.

greenpau avatar Mar 09 '24 02:03 greenpau