Why does the DefaultTokenServices#createAccessToken method bothers retrieving existing access tokens for a given authentication, and deliver the same tokens again if they are still valid ?
From the source code it seems to be made on purpose :
// Only create a new refresh token if there wasn't an existing one
// associated with an expired access token.
// Clients might be holding existing refresh tokens, so we re-use it in
// the case that the old access token
// expired.
Sounds like a client concern to me.
Since both access and refresh token are delivered again, is it worth the complexity and database roundtrips ?
Also when a client submits a _password_ or _client credentials_ grant right before an existing token expires, he gets the same token with a very limited validity.
If a client is asking for an access token I think it is reasonable to give them back the one they already have, if we know about it. Putting more data in a database than necessary just seems like it will lead to headaches later - an access token is a record of a grant, so it's a good repository for that interaction, and logically a user has only granted access to one set of scopes and resources.
The comment you highlight is in the method that creates an access token, not the method that refreshes one from a refresh token. Note that in the latter case there is a flag (reuseRefreshToken) to signal that you don't want to re-use the existing refresh token, which is how you avoid the "short validity" problem that you mention.
I'm not sure we need to change anything really, and whatever we did change I doubt it would result in less trips to the database (I don't think that's a valid concern). I suppose re-issuing a refresh token if an access token is re-used and reuseRefreshToken=false might be a sensible move. In practice I've never had any issues though if the clients are well behaved.
Thanks for the answer. It's true that robust clients should check their token validity before using them, and if a refresh token is available there's no issue.
I'm worried about one use case, when an installed application is using the _password grant_ as its _authentication_ mechanism. Technically the user "session" length on the device is determined by the access token validity, and there is no refresh token there. I didn't want users to have to type their passwords twice in a short span (or worse, the app storing credentials locally).
I'll try to extend ResourceOwnerPasswordTokenGranter to invalidate existing tokens for that specific grant type.
Didn't know I could activate refresh tokens for the _password grant_ out of the box.
Problem solved :heavy_check_mark:
@dsyer Hi Dave, based on the last comment from @michaeltecourt do we still need to act on this?
Definitely not urgent I would say. I can see some value in having the option to re-issue a token though, so I wouldn't close it for good.
@dsyer Is it normal that when i get a new access token using a refresh_token the refresh_token generated in response was the same that i use in the request? I think that i would have to get a new refresh_token with expiration time increased
Yes it's normal. Did you see the reuseRefreshToken flag (comment above)?
Note that in the latter case there is a flag (reuseRefreshToken) to signal that you don't want to re-use the existing refresh token, which is how you avoid the "short validity" problem that you mention.
I cannot fix the "short validity" bug.
I have a modal that prompt my user if he want to renew he's access_token. If the token returned by the login is the same, then I have a disconnection.
I have tried to play with the reuseRefreshToken. I am able to renew and get a new refresh_token
I've also seen a defaultTokenServices.setSupportRefreshToken(true);
I have a similar problem, but maybe I missunderstand something.
I'm using JWT Tokens with the resource owner password grant. When I refresh a token, the new access token refreshs its expiry, but the refresh tokens expiry remains always the same as the original one from the password grant - means not really renewed. I set defaultTokenServices.setSupportRefreshToken(true); and indeed get a new token (looks different), but its validity is not refreshed.
I have also posted to stackoverflow where the process and the tokens are described and there you can see that the expiry is always the same.
Use Case should be something like this:
Short Validity for access token (say 1 minute) and a bit longer for refresh token (say 30 minutes).
User gets token user password grants and may work for a minute. After this minute his token is expired, but he can get new one as long a he refresh at least every 30 minutes. Expecting that the refresh tokens validity is always extended for 30 minutes by each refresh.
It seams that my assumptions are wrong, or there might be some bug. At least the described Use Case is not working at the time.
So here my questions (the first is similar to the first of @kopax):
@niggusch you dont have to change property 'SupportRefreshToekn' to false, the property you have to change is 'reuseRefreshToken' with value false. This property is in defaultTokenServices too.
@serbande Sorry my mistake, that's what I already did. I corrected my previous post.
Here is my config.
```
@Bean
@Primary
public DefaultTokenServices tokenServices() {
DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
defaultTokenServices.setTokenStore(tokenStore());
defaultTokenServices.setSupportRefreshToken(true);
defaultTokenServices.setReuseRefreshToken(false);
defaultTokenServices.setAccessTokenValiditySeconds(this.accessTokenValiditySeconds);
defaultTokenServices.setRefreshTokenValiditySeconds(this.refreshTokenValiditySeconds);
return defaultTokenServices;
}
`
``
You can configure the behaviour:
public void configure(AuthorizationServerEndpointsConfigurer endpoints)
throws Exception {
endpoints.reuseRefreshTokens(false);
}
Most helpful comment
I have a similar problem, but maybe I missunderstand something.
I'm using JWT Tokens with the resource owner password grant. When I refresh a token, the new access token refreshs its expiry, but the refresh tokens expiry remains always the same as the original one from the password grant - means not really renewed. I set
defaultTokenServices.setSupportRefreshToken(true);and indeed get a new token (looks different), but its validity is not refreshed.I have also posted to stackoverflow where the process and the tokens are described and there you can see that the expiry is always the same.
Use Case should be something like this:
Short Validity for access token (say 1 minute) and a bit longer for refresh token (say 30 minutes).
User gets token user password grants and may work for a minute. After this minute his token is expired, but he can get new one as long a he refresh at least every 30 minutes. Expecting that the refresh tokens validity is always extended for 30 minutes by each refresh.
It seams that my assumptions are wrong, or there might be some bug. At least the described Use Case is not working at the time.
So here my questions (the first is similar to the first of @kopax):