storing AuthorizationCodeCredential in web app session - spring-boot

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.

Related

springboot APIs to use Auth0

We are trying to use auth0 for spring-boot application authentication.
Created Regular Web Application and Machine to Machine Applications in auth0.com and added users under User Management.
Intention is to have a login API to authenticate users and get the access-token after the successful authentication. Use access token (as bearer token) to access other APIs of the spring-boot application.
We provided proper login and callback urls under the Machine To Machine application configuration in auth0.com.
While generating bearer token, apart from client_id, client_secret we have provided grant_type (as client_credentials), audience as https://<>/api/v2 and scope with (openid profile my_scope email roles).
We are getting 401 error while accessing the other APIs using bearer token generated using client_id, client_secret, grant_type and audience.
Wherein, we are getting 403 error while accessing the other APIs using bearer token generated using client_id, client_secret, grant_type, audience and scope.
403 error stack is as below
Client is not authorized to access <<application-domain-in-auth0>>/api/v2/. You need to create a client-grant associated to this API.
We referred to the udemy session (https://www.udemy.com/course/build-secure-apis-with-auth0-and-postman/learn/lecture/12716335#overview)
Any inputs on the overall approach and where we are going wrong.
Thanks
Venkata Madhu
not sure if it can help, but found this more relevant to the problem statement.
https://community.auth0.com/t/how-to-generate-a-management-api-token-automatically/6376
There are a few things you need to do/check:
Create a non-interactive client in Auth0, which will be used to represent your service.
Authorize the non-interactive client to call the Auth0 Management API:
Dashboard > APIs > Auth0 Management API > Non Interactive Clients > Authorize your client
Ensure that the parameters used in the call to /oauth/token are for your non interactive client:
{
grant_type: 'client_credentials',
client_id: 'NON-INTERACTIVE-CLIENT-ID',
client_secret: 'NON-INTERACTIVE-CLIENT-SECRET',
audience: 'https://yourdomain.auth0.com/api/v2/" }
Make sure the access token you receive is passed in the Authorization header for every request made to the Management API. Authorization: Bearer <access_token>

Keycloak and Google login

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!

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

Multiple Access token with one refresh token

I have multiple mobile clients and they all authenticate using the password grant flow. For this, I just want to use one very long lasting refresh token with multiple shorter-lived access tokens. I have been trying to generate multiple access tokens with Password Grant in spring, however, anytime I refresh my access token the old access token stops working. I checked the database and there is only one record in the oauth_access_token table at all times for that specific authentication. Isn't Spring Oauth2 supposed to generate multiple access tokens for one refresh token?
Thank you for the help.
It is supported by OAuth2 specification, see RFC 6749:
1.5. Refresh Token
Refresh tokens are credentials used to obtain access tokens. Refresh
tokens are issued to the client by the authorization server and are
used to obtain a new access token when the current access token
becomes invalid or expires, or to obtain additional access tokens
with identical or narrower scope (access tokens may have a shorter
lifetime and fewer permissions than authorized by the resource
owner).
But Spring Security OAuth2 doesn't support it, see DefaultTokenServices#refreshAccessToken:
// clear out any access tokens already associated with the refresh
// token.
tokenStore.removeAccessTokenUsingRefreshToken(refreshToken);
and TokenStore#removeAccessTokenUsingRefreshToken:
Remove an access token using a refresh token. This functionality is necessary so refresh tokens can't be used to create an unlimited number of access tokens.
One work-around is to implement a custom TokenStore.
The goal here is to make it possible for multiple devices to work with different tokens independently of one another. It turned out that in Spring OAuth we cannot have one refresh token with multiple access tokens associated with it. It also turned out that it was not necessary to have such a configuration; as long as we can have separate authentications for separate devices, that would suffice. Now, a key is generated(DefaultAuthenticationKeyGenerator) based on client_id, scope, and username. As I am not using the scope, I simple put the device info in the scope and got the following:
{
"access_token": "32e11a1b-cb9f-4317-95b0-e850f260d160",
"token_type": "bearer",
"refresh_token": "d097e4ea-a9d9-4e0c-94cd-7c15e1c8e690",
"expires_in": 3599,
"scope": "android2",
"exp": 1557843628674
}
To make this happen, just leave out the scope configuration as follows:
public void configure(ClientDetailsServiceConfigurer configurer) throws Exception {
configurer
.inMemory()
.withClient(CLIENT_ID)
.secret(passwordEncoder.encode(CLIENT_SECRET))
.authorizedGrantTypes(GRANT_TYPE_PASSWORD, AUTHORIZATION_CODE, REFRESH_TOKEN, IMPLICIT)
// ************* Comment this out ******
//.scopes(SCOPE_READ, SCOPE_WRITE, TRUST)
.accessTokenValiditySeconds(ACCESS_TOKEN_VALIDITY_SECONDS).
refreshTokenValiditySeconds(REFRESH_TOKEN_VALIDITY_SECONDS);
}
Using this method, each and every device can get a separate token. Also, when the user logs out, we have the option of logging him out of all his devices.
However, we cannot leave out the scope in our requests; the scope parameter must always be sent in refresh token requests.

How does Ruby's rest-client work for OAuth 2?

I am trying to implement an OAuth 2 sign up for an Angular 6, using gitLab Api. Its website has some code for getting the access token based on Ruby. I will be so glad if anyone lets me know how to get this access token.
OAtuth 2 for gitLab says that I can get the secret code and YOUR_UNIQUE_STATE_HASH. I managed to follow their instruction.
To get the access token, gitLab posted some Rubi [sic] code, which I could not understand and don't know how to implement in angular.
Here is the instruction:
Once you have the authorization code you can request an access_token using the code, to do that you can use any HTTP client. In the following example, we are using Ruby's rest-client:
parameters = 'client_id=APP_ID&client_secret=APP_SECRET&code=RETURNED_CODE&grant_type=authorization_code&redirect_uri=REDIRECT_URI'
RestClient.post 'http://gitlab.example.com/oauth/token', parameters
# The response will be
{
"access_token": "de6780bc506a0446309bd9362820ba8aed28aa506c71eedbe1c5c4f9dd350e54",
"token_type": "bearer",
"expires_in": 7200,
"refresh_token": "8257e65c97202ed1726cf9571600918f3bffb2544b26e00a61df9897668c33a1"
}
I would be so kind if somebody explains this code snippet.
The snippet is basically doing as denoted already. You need to generate the access token (or bearer token) using your client id and client secret with the code which was returned after successful user auth - this access token is basically the token which you will then further use on behalf of user to gitlab.
OAuth makes sure that the client code cannot be used by unauthorized attacker by making sure that you as a developer request it with your client id and client_secret.
RestClient.post 'http://gitlab.example.com/oauth/token', parameters will send that POST request and then Gitlab will return the response with access token and about it's expiry.

Resources