I have a spring boot controller, that invokes a service on wso2. (sends an identity and receives a token for further communication). I am looking for a way to auto-refresh the token on the spring boot side (because the invocation of the service on wso2 is not done by a browser, but rather by another service).
So, on the spring boot side, how can I achieve that? I understand that I should check the expiration date of the access_token and use the refresh_token to receive a new access_token, but is there some library that does that or do I have to code this logic myself? Also, when running my app on multiple instances of spring boot, how do I prevent the token being refreshed from one instance and invalidating the token on another instance, using the same token?
OAuth2 provides five grants for acquiring the access token. One of them is the refresh token grant which is used to obtain a new access token after the client has been authorized for access and the token already expires. In the refresh token grant, the client sends a POST request to the authorization server with the following parameters:
grant_type=refresh_token&client_id=your_client_id&client_secret=your_client_secret
&refresh_token=your_refresh_token_from_the_first_grant
The auth url should be same the first time you obtain the token. For auto-refreshing the token, you can catch for HttpClientErrorException when you access the resource server and check if the status code is HttpStatus.UNAUTHORIZED. If it is, then send request for new token.
try {
response = getRestTemplate().exchange...
} catch (HttpClientErrorException e) {
if (e.getStatusCode().equals(HttpStatus.UNAUTHORIZED))
//code to refresh the token or throw custom exception...
}catch (Exception e) {
//
}
For multiple instances of the client, this might help you: Spring Oauth2 - multiple tokens per client id
I have not verified it but essentially it uses the scope in the post parameter to generate a different token for the same client_id.
Related
Currently I am using /token endpoint to obtain an access token, an ID token (by including the openid+offline_access scope), and a refresh token for the Authorization Code flow. The value for code is the authorization code that I receive in the response from the request to the /authorize endpoint.
Also to refresh access token as well as an ID token, I am sending a token request with a grant_type of refresh_token.
Below is the reference link, I am trying similar to implement in my custom OIDC application.
https://developer.okta.com/docs/guides/refresh-tokens/main/#renew-access-and-id-tokens-with-spas
Does it suppose to return both refresh_token and id_token OR both are optional if grant_type=refresh_token (also in token endpoint openid+offline_access scope added) in OpenID Connect concept?
Below is the link I am trying to understand.
https://openid.net/specs/openid-connect-core-1_0.html#RefreshTokens
When you use the refresh token, the purpose is to get a new access token. Optionally, depending on the backend configuration, you might get a new refresh token as well (if you use a one-time refresh token setup).
You never get a new ID-token back, the ID token is usually a very short-lived token (like 5 minutes) and its main purpose is to describe how the user is authenticated and who it is. The main purpose of the ID token is to create the local session (typically a session cookie), after that the ID token has no real use.
Client application fetches the idtoken for authentication. But for the resource server, it needs to again make a call to Auth server and fetch the access token. Hence, does it make sense to make two calls for every oauth2.0 flow. The access token is what will be sent to the resource server. Am I missing something here.
With OpenID Connect, the ID-token is returned to the client at the same time as the access-token. So there is no specific need to make two requests to get the two tokens.
If you ask for an refresh token as well, then that one will also be returned at the same time.
The API (Resource Server) only receives access tokens from the client and it can without asking the identity provider validate the token. The API does not receive any ID-token.
I have an ASP.net MVC web application that uses Microsoft's Owin middleware (Microsoft.Owin.Security.OpenIdConnect) to configure OpenID Connect authentication. My identity provider (Okta) is configured to support refresh tokens and I have confirmed that it is working. When signing in, my application receives an Access, ID and Refresh Token as expected. These tokens are validated and returned to the client in a cookie called ".AspNet.Cookies" (the default). On each request, the cookie and these tokens are parsed into a set of claims. Great so far. 👍
The Owin (Katana) middleware does not appear to do anything further with the Refresh Token, so I have implemented a token client to request a new Access Token from my IdP using the Refresh Token. This is working as expected. 👍
Two questions:
When and where should the application check to see if the Access Token is expired and request a new one?
After receiving new a access, id, and refresh token, how and where should the application update the user identity, claims and cookie?
OWIN COOKIE UPDATES
I believe the comment at the end of this post has the type of code you can write - I remember using similar code a few years back.
With OWIN you are using a server side stack secured by cookies so I'm not sure where access tokens are actually used, but maybe one of these is true?
The C# back end uses tokens to call an API
The Web UI downloads tokens from the web back end and makes Ajax calls to an API
PATTERN FOR HANDLING EXPIRED TOKENS
The only reliable pattern to handle expiry is to do this in the API client code:
When you get a 401 response from the API
Try to refresh the token and retry the API call with a new access token
If you can't refresh the token, redirect the user to sign in again
I always implement this with 2 classes, as in this SPA code of mine:
ApiClient - handles API calls
Authenticator - handles OAuth calls
If the Web UI is getting tokens from the web back end and then calling an API, your web back end could provide MVC operations similar to those in my authenticator class:
getAccessToken - get the current access token, though it may fail with a 401
refreshAccessToken - use this if a 401 is received and you need a new token
TOKEN EXPIRY TIMES
It is also possible to check token expiry times in the background - to reduce the number of client 401s. This is not a full solution however, since 401s can occur for other reasons in addition to expiry.
With the introduction of OAuth2AuthorizedClientManager in Spring Security 5.2, it's possible to handle the authorization of OAuth2 clients with HTTP clients or abstractions other than WebClient.
We could use something like
OAuth2AuthorizedClient authorizedClient = authorizedClientManager.authorize(
OAuth2AuthorizeRequest
.withClientRegistrationId("registration-id")
.principal("client-id")
.build()
);
Reference: https://github.com/spring-projects/spring-security/issues/8018#issuecomment-601183465
Although I can now get an access token from the OAuth2AuthorizedClient (e.g. String accessToken = authorizedClient.getAccessToken().getTokenValue()), I must always first call authorizedClientManager.authorize(oAuth2AuthorizeRequest) to ensure that I have a valid access token before calling a downstream service. If the access token is expired, the authorize call will perform a Client Credentials call to the token endpoint and get a response back with a fresh token. However, if my microservice receives multiple calls at the same time (e.g. on different request threads), the authorize call could theoretically call the token endpoint for every request thread because each request thread will determine that the access token is expired and request a new one before calling the downstream service. Only once the the OAuth2AuthorizedClientRepository is updated with a valid token, will the request threads stop invoking more token endpoint calls. Also, there may be a flurry of token endpoint responses that will overwrite each other with the final response's access token getting persisted in the the repository until the next expiration.
I'd like to find a way to efficiently authorize client credentials clients in a multithreaded context so that I don't trigger a race condition of token requests. The only ways around this that I can think of is to schedule authorizations before the access token expires or for Spring Security to prevent multiple token endpoint calls if it's waiting for the first response.
Any suggestions would be greatly appreciated.
I want to create the single page application with token based authentication with Auth0.
My authentication use case is:
1.) Insert the username and password
2.) Get the token from Auth0 server with expiration time perhaps 6 hours
3.) In javascript side I check the expiration time of current token
4.) If the token will be before its expiration I call the function renewIdToken via Auth0.js library. It is HTTP POST to the delegation endpoint of Auth0 server.
auth0.renewIdToken(current_id_token, function (err, delegationResult) {
// Get here the new delegationResult.id_token
});
https://auth0.com/docs/libraries/auth0js
5.) If the token will be expired then I redirect to the loginpage.
Is secure be able to renew the token via HTTP POST from anywhere?
What's happend if the user lost the token and attacker can use this token forever because is easy to renew it and the token is not possible revoke.
This scenario is without refresh token, I only work with token.
I read some topics where is not recommended use the refresh tokens in the SPA scenario.