I have succesfully set up Google as Identity Provider in Keycloak, following the docs, and I'm now able to login to my application using keycloak.
Is there a way to get the user data from the google account that is logged in. In my application I would like to retrieve profile information like in this example and then add it later to my mappers so I could see it in my Access Token(Adding attributes in my access token is not an issue, that works fine)?
Try making a request against the userinfo endpoint
https://www.googleapis.com/oauth2/v3/userinfo?Access_token=XXX
It should work but you may have to add a profile scope to your request i cant remember.
Related
I have have integrated a OAuth 2.0 Resource Server in my spring boot application using JWT and issuer URL as describe here: https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2resourceserver I am integrating against AWS Cognito service and everything is working, however I am missing the information I want.
I am currently receiving the Access Token from the React front-end which does not contain any custom attributes for the user, only groups. As stated by the documentation here: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-tokens-with-identity-providers.html
Is there a way to get the custom attributes through the use of an access token, through a callback or something to Cognito?
Alternatively I could receive the ID token directly however after browsing around this does not seem like the best practice? I am pretty new to implementing OAuth 2.0 so I am not sure about all the pros and cons.
The /oauth2/userInfo endpoint will provide you information about the authenticated user.
https://docs.aws.amazon.com/cognito/latest/developerguide/userinfo-endpoint.html
I'm currently using OAuth with the password grant type to manage the security of my Spring Boot application. Now I want to store a login id which is queried by the auth server from the database when the client has successfully requested an access token.
To realize this I thought of passing it with the JWT. I used a custom TokenEnhancer in combination with a TokenChain to add the additional login id, which works fine. My problem is that I couldn't find a way, other than parsing the token myself, to get that login id.
Another, but a very bad solution could be to just pass it as authority.
I want to create a login with google option and give authorities to the user depending on the user info returned. I've successfully done what I want for login with github following this tutorial:
https://www.baeldung.com/spring-security-oauth-principal-authorities-extractor
which basically uses #EnableOAuth2Sso annotation and the following properties
security.oauth2.client.client-id
security.oauth2.client.client-secret
security.oauth2.client.access-token-uri
security.oauth2.client.user-authorization-uri
security.oauth2.client.scope
security.oauth2.resource.user-info-uri
I can't do the same for google, so the problem should be in application.properties. I register my app with google, download the json that is given to me along with id & secret, but there seems to be missing the uri for security.oauth2.resource.user-info-uri property. I've searched online for that uri and tried to run the app with some values but with no success. Am I right that I need this property and how do I find it?
You need to request this information during authorization via scopes. This information is returned in the Identity Token and not the Access Token. If you requested the identity information you can also call the Google OAuth endpoint with the Access Token which returns the Identity Token.
We have a web app in which we allow users to log into the app using any Open ID provider(e.g. Okta, Google, Facebook etc.). We want to implement the correct Open ID Connect prescribed methodology/workflow to keep the user logged into the site.
The existing implementation, looks at the expiry of the Access Token then if it's close to expiry uses a Refresh Token to get a new Access Token to keep the user logged in. I feel like this is wrong. When a user logs in to the web app, the Identity Token is used to Authenticate the identity of the user using the Authorization Code workflow. The Access Token and Refresh Token are stored on the server side. Periodically, the Refresh Token is used to get new Access Tokens to keep the user logged into the site. I believe this is a security risk because -
Imagine if a user is logged onto his OP account in a browser. He opens up Sky and is directly logged into MP because he’s already logged into MP. He then in a separate tab, logs out of his OP account. He will continue to be logged into MP for days on the basis of this Refresh Token/Access Token mechanism! Isn’t this a security risk?
If feel like the correct way to go about this is to use Session Management using iframes as prescribed here on OIDC -
https://openid.net/specs/openid-connect-session-1_0.html
For more context, when a user logs into our WebApp we pull data from the OP's UserInfo endpoint to create a profile within our WebApp and set permissions/roles within our app based on data sent over from the OP's UserInfo endpoint. We continue doing this periodically. For this purpose, I feel like using the Access Token(and using the Refresh Token to get new Access Token) to access the UserInfo API is correct because it conforms to the OAuth 2.0 concept of protecting/authorizing API/Resource endpoints using Access Tokens.
I want to know if this is indeed the correct way to manage how a user should be logged in when supporting Open ID Connect.
I think the first question is whether you want to bind the lifetime of an OpenID Connect provider Single Sign On session with the session of your application. You just want to authenticate a user using their OpenID Connect service. If I logout of Google, I expect to be logged out of GMail, but not a third-party application that used Google for authentication. Would you like to implement Single Sign Out as well?
But if I wanted to be logged out when you logout of the OpenID Connect provider, I would implement the OpenID Connect Session management. There is one thing good to be aware of when using iframes and cookies - browsers have an option to "Block third-party cookies" (that's how Chrome calls it), it's turned off by default, but as far as I know, it disables the SSO functionality when turned on.
I'm not sure why you request the userinfo endpoint periodically. If you just want to check whether the access token is still valid, you could also use the token introspection endpoint.
For security concerns, I would suggest you to read the OAuth 2.0 for Browser-Based Apps RFC. It recommends using the auth code flow with PKCE instead of the implicit flow. With the implicit flow, access tokens transported in redirect URLs stay in network and browser caches and can be used right away by an attacker. The auth code with PKCE needs a code_verifier (one-time secret) in order to be exchanged for tokens. So I would first check how the providers work with a configuration you choose and if it's even supported.
I have an auth server built using spring boot oauth2.0 and follows david_syer model.
My auth server does following -
Let user login via third party oauth provider like google or let user create his account on our server using username and password and generate token.
So, when user uses external oauth like google to login then I simply store the token and pass the same(google) token to my UI app for accessing resource api servers. I have an authentication filter that verifies token and allow api access.
When user uses username and password to get token we store user and his permissions and generate a token for him. Now UI uses our auth servers generated token to access resource api servers.
Now my question is
Is this the correct way of using token from external api and using the same to access our resource api server?
And how do I add authorities to user who are signing up using 3rd party oauth provider since I don't add user entry and authorities for them?
So, spring security which loads user and user authorities (loadUserByUsername() from UserDetailsService) will not have any thing if user came from eternal provider.
I have a suggestion for step 2:
After the user uses the google authentication, and gets redirected back to your application page, do the claims transformation on your server and generate your own token issued by the identity server that you have.
The reason is you will be able to provide specific claims and the claims names does not necessarily required to match up.
That way you keep verifying your own token all the time on the client app. So lets say the user uses Facebook instead of Google and even in that scenario as you will assign your own token, you need not to verify the token coming from different third party Identity servers.
That way, your identity server trusts Facebook, Google provided token and your application will trust only your identity server so your app doesn't need to know about what IDP is issuing the token.
And with the approach I suggested above, you will be able to even modify the claims for the user on your own and don't have to depend upon the third party identity server to provide claims.