Keycloak and Google login - spring

Currently I am developing Spring Boot application which need to have Keycloak login. I managed to make Google registration and when I get registered I getting this response:
{
"access_token": "ya29.dJnTYLwF7cBoJOHal1-8Efn9sw6oacGhA_JLiruKk2jOqBoAqgPpKa1gSmFferDvj-1D2mYg_jxEHUMVatz8z-F3L4e5A8l_AixFeRPmg4C_nnA--Pdvxwl1moglBbwjaJTJTUmE4yh1PzPnbBiZ",
"token_type": "Bearer",
"expires_in": "3599",
"id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6Ijc0MjE3YjhkYWRiYjM2NTc4MzU4MGY5ZTkyNDg3ZDTYiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXpwIjoiODY5Njc1Nzc0MjgxLTY4ZmExbjY3ZW41NW5zb3YyaGdib2JtZG05c3VlMDB1LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiODY5Njc1Nzc0MjgxLTY4ZmExbjY3ZW41NW5zb3YyaGdib2JtZG05c3VlMDB1LmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTAxNDE4ODQ2MDM0MzI5Nzk0ODcwIiwiZW1haWwiOiJtYXJpbnNwYWppYzE5OThAZ21haWwuY29tIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF0X2hhc2giOiJlbno5VDhuc3NLSHNqaEdVbFZQV253IiwiaWF0IjoxNjMxNTUzNjAyLCJleHAiOjE2MzE1NTcyMDJ9.oU_LAWPQU0RJ5yMM7M-xtKdM1rpLy2xqIg46kHu0KWR_1_2IY_tc3Uf1v2nNoEAQVXnZVbScUaHspwNny8yDirybxgOX_73aPGzb_FmcjVqgLTZTt8dbjizgy412cNFskH3GuRAXRMZppDbPPKlE2sgceMxapboCuivXIRyAyDQ_uXHSINEaPKFE3Tqjx-x6T6epcqY8M4hCt8Obs929BT86e3Ky6Xj1DUBv5UMm1Hk8NxoD_JU-rFLPQx-FZrVV3kYkdbJWKpoUVU-CToXDR4yRmxYXoz2kZMlc-rgugxxJ3OKG-JotVfSDh5Vp5iHy9kUpHOxi_8vWKw28LwNNhA"
}
Now I have to take access token and other information from Keycloak by this tokens, but I really don't know which endpoint I have to shoot.
Is there some example of login with Google or some advice ? Thanks!

Related

How to get username / userinfo in Spring OAuth2 Resource Server

I have an api which uses AD Token for authorization.
I am trying to fetch the username of the user inside my service component. But im failing to. I have tried this.
val authentication: Authentication = SecurityContextHolder.getContext().authentication
println(authentication.name) // Random short string with 3 "-". Not JWT
println(authentication.details.toString()) // WebAuthenticationDetails [RemoteIpAddress=127.0.0.1, SessionId=null]
println(authentication.authorities.toString()) // Prints Scope [SCOPE_User.Read]
println(authentication.principal) // org.springframework.security.oauth2.jwt.Jwt#xxxxxxxx
The token is from AD and it does contain userdata. The payload contains these fields with user related stuff. I removed the rest.
{,
"family_name": "Wick",
"given_name": "John",
"name": "WickJohn",
"roles": [
"User"
],
"scp": "User.Read",
"unique_name": "wickjo#gmail.com",
"upn": "wickjo#gmail.com",,
}
Anyone have any idea?
I solved it easily just reading the jwt manually.
val authentication = SecurityContextHolder.getContext().authentication
val jwt = authentication.principal as Jwt
println(jwt.claims["name"])
Still would be interesting to find out why i didnt get it automatically
To get username/user info in Spring OAuth2 Resource Server, please try the below:
Make sure to configure resource server in the Authorization Server too.
To get user info by token, resource server provides a filter OAuth2AuthenticationProcessingFilter
The generated token is set into SecurityContextHolder.
Otherwise, When accessing userinfo try including the access token in the header (Authorization Bearer).
If the above doesn't work, then try using On Behalf Of Flow and the code mentioned in this GitHub blog.
For more information, please refer below links:
Azure AD 2.0 Troubleshooting – OAuth Architecture Guidance (authguidance.com)
How to get userinfo by jwt token in spring security oauth2 authorization server? - Stack Overflow

Laravel using basic.auth access_token

i am follow laravel documentation about Basic Authentication
i already create an API who response
"token_type": "Bearer",
"expires_in": 31536000,
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9"
and i use the access_token on postman as
Header
Authentication : Bearer {{access_token}}
and set my route with Route()->middlewire(auth.basic)
the response always
{
"message": "Invalid credentials.",
"exception": "Symfony\\Component\\HttpKernel\\Exception\\UnauthorizedHttpException",
...
What I do wrong?
I figure it out
i did not read the right documentation
I read basic auth documentation on laravel but actually I use basic auth with passport and on passport the middleware is not auth.basic but client, now i can use the return access_token

storing AuthorizationCodeCredential in web app session

I am using the azure-identity library to authenticate users for accessing the Microsoft Graph API in my Spring Boot web application.
After getting the successfully getting the code via auth code grant redirect I want to store the access token and refresh token in the the web application session so that the user does not have to re-authenticate for doing multiple requests to the Microsoft Graph API.
How can I get hold of the tokens for storing them in the session?
The Authorization Code is a single-user code used to obtain an actual Access Token. You'll need to redeem that code for an access_token as described in Microsoft identity platform and OAuth 2.0 authorization code flow.
The response body that contains the access_token will also include a refresh_token value:
{
"access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Ik5HVEZ2ZEstZnl0aEV1Q...",
"token_type": "Bearer",
"expires_in": 3599,
"scope": "https%3A%2F%2Fgraph.microsoft.com%2Fmail.read",
"refresh_token": "AwABAAAAvPM1KaPlrEqdFSBzjqfTGAMxZGUTdM0t4B4...",
"id_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJhdWQiOiIyZDRkMTFhMi1mODE0LTQ2YTctOD...",
}
The way to do this was to create a class that implements OAuth2AuthorizedClientService that stores and loads the OAuth credentials in the database.

Google API access token meaning

Somebody has created a system which use Google API. It happens that I have been using this system for several months to upload files to G Drive and it worked very well.
However today I realized in the following string that there was an expiry date (not updated until today) which prevent from uploading files. My understanding is that a token is generated every time my code is requesting API access, but this shows the same access_token and refresh token with expiry date. I tried to read official doc without clear understanding. Can you explain simply what I should think about it and hint at how I should re generate the needed token please.
{"access_token": "xxx", "client_id": "yyy", "client_secret": "nnn", "refresh_token": "bbb", "token_expiry": "2021-02-24T05:33:24Z", "token_uri": "https://accounts.google.com/o/oauth2/token", "user_agent": null, "revoke_uri": "https://oauth2.googleapis.com/revoke", "id_token": null, "id_token_jwt": null, "token_response": {"access_token": "xxx", "expires_in": 3599, "scope": "https://www.googleapis.com/auth/drive", "token_type": "Bearer"}, "scopes": ["https://www.googleapis.com/auth/drive"], "token_info_uri": "https://oauth2.googleapis.com/tokeninfo", "invalid": true, "_class": "OAuth2Credentials", "_module": "oauth2client.client"}
How much i understood it is that as we need multiple parameters to access a Google API which include authentication etc. As there are multiple steps to validate an API call, if they succeed, we are provided with an access_token which now represents that all the processes (or authentication etc) was successfull and now the access_token is a proof for that. So after that, only the token will be checked (until its expiry date) and the process will repeat after the expiration.
The authorization sequence begins when your application redirects a browser to a Google URL; the URL includes query parameters that indicate the type of access being requested. Google handles the user authentication, session selection, and user consent. The result is an authorization code, which the application can exchange for an access token and a refresh token.
The application should store the refresh token for future use and use the access token to access a Google API. Once the access token expires, the application uses the refresh token to obtain a new one.
More details Here

redirect_uri_mismatch the redirect URI in the request does not match the ones authorized for the OAuth client

I have following client secret
{
"web": {
"client_id": "testid",
"project_id": "testproj",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://www.googleapis.com/oauth2/v3/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "test-sec",
"redirect_uris": [
"https://localhost:8080/oauth2callback"
]
}
}
and I am getting
"Error: redirect_uri_mismatch
The redirect URI in the request, http://127.0.0.1:8414/authorize/, does not match the ones authorized for the OAuth client.
To update the authorized redirect URIs, visit:". Could you please suggest, how to fix it.
I am using C#. I have created credentials with this -
GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.Load(stream).Secrets, scopes,
"user",
CancellationToken.None,
new FileDataStore(Directory.GetCurrentDirectory() + "\\AccessToken\\" ,
true)).Result;
But for first time , it popped up with login and once I logged in , it has created Google.Apis.Auth.OAuth2.Responses.TokenResponse-user file in the folder. Is there a way to bypass first time login ?
Thanks.
When you are creating your credentials in https://console.developers.google.com:
After cliking on Create credentials by choosing OAuth client ID:
Choose Other as Aplication type:
.
You should have this format of credentials:
{
"installed": {
"client_id": "...",
"project_id": "...",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_secret": "...",
"redirect_uris": [
"urn:ietf:wg:oauth:2.0:oob",
"http://localhost"
]
}
}
Now your OAuth2 link should works whatever your port in redirection_uri paramater as http://localhost:8414 for example (with 8414 as random port). And you are no more this error:
Error: redirect_uri_mismatch The redirect URI in the request, http://localhost:8414/authorize/, does not match the ones authorized for the OAuth client.
I just ignored the port in the error message when adding as an Authorized redirect URL.
http://127.0.0.1/authorize/
The redirect uri is the URL where you want Google to return the authencation to. This should be the file that you have set up to handle the Oauth response.
When you created your project in Google Developer console you should have supplied a redirect uri to google that states where you will be sending from and where you would like the response to be returned to.
"Error: redirect_uri_mismatch The redirect URI in the request, http://127.0.0.1:8414/authorize/, does not match the ones authorized for the OAuth client.
means that you are sending from http://127.0.0.1:8414/authorize/ however this is not one of the redirect uris that you have added in Google developer console. Go back to the developer console and add this http://127.0.0.1:8414/authorize/ or http://localhost:8414/authorize/ you may or may not need the ending / as well
Bypass Login
What you need to understand is that most of Googles api data is private user data. In order to access private user data you must have the consent of the user who owns that. We use Oauth2 to request from the user consent for our application to access their data. There is no way to by pass an oauth2 consent.
Unfortunately there is no other way to access the YouTube api. If you want to access private user data you will always have to ask the user for consent at least once and then save the credentials as you are doing now using file data store.
If you're using container apps or web apps contained over Linux, refer this answer. It could be caused by authentication redirecting to provider handle that's not served over HTTPS. See the error for redirect_uri and if the link is over http, follow the same.

Resources