Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring OAuth2: Validity Period of RefreshTokens is not renewed

I'm using the resource owner password grant with spring-security-oauth in backend. The Tokens are JWT.

I would like to have short living access tokens (say 2 minutes) but long living refresh tokens( say on hour).

As I understand, after the first login the access token should be valid for 2 minutes and the refresh token for 1 hour. And that is. But thats it. When I refresh the token, the validity remains unchanged. It seems that the original expiry from the password grant is still valid and the refresh is some kind of ignored. Indeed I get a new token, but the expiry is the same as from the password grant.

    @Bean
@Primary
public DefaultTokenServices tokenServices() {
    DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
    defaultTokenServices.setTokenStore(tokenStore());
    defaultTokenServices.setSupportRefreshToken(true);
    defaultTokenServices.setReuseRefreshToken(false);

    // 2 minutes        defaultTokenServices.setAccessTokenValiditySeconds(this.accessTokenValiditySeconds);
    // 1 hour        defaultTokenServices.setRefreshTokenValiditySeconds(this.refreshTokenValiditySeconds);
    return defaultTokenServices;
}

Login with password flow

curl -v -u my-trusted-client:secret -d 'grant_type=password&username=XXX&password=$PASS' http://$AUTH_HOST:$AUTH_PORT/$AUTH_CONTEXT/oauth/token

returns something like that:

{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiYXV0aDItcmVzb3VyY2UiXSwidXNlcl9uYW1lIjoibXIubmlnZ3VAZ21haWwuY29tIiwic2NvcGUiOlsicmVhZCIsIndyaXRlIiwid2hhdGVydmVyIl0sInVzZXJOYW1lRnJvbVVzZXIiOiJtci5uaWdndUBnbWFpbC5jb20iLCJleHAiOjE0ODk2NzkyMDMsImF1dGhvcml0aWVzIjpbIlJPTEVfQURNSU4iXSwianRpIjoiMDFlZmZiNjEtYzFjMy00ZWExLWEwNWEtNGUyYWM3ZTViMDVmIiwiY2xpZW50X2lkIjoibXktdHJ1c3RlZC1jbGllbnQifQ.fsab4mAi3eik5Yd82v3l_EZ1CB75ppZPrSKp8pcg3WA","token_type":"bearer","refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiYXV0aDItcmVzb3VyY2UiXSwidXNlcl9uYW1lIjoibXIubmlnZ3VAZ21haWwuY29tIiwic2NvcGUiOlsicmVhZCIsIndyaXRlIiwid2hhdGVydmVyIl0sInVzZXJOYW1lRnJvbVVzZXIiOiJtci5uaWdndUBnbWFpbC5jb20iLCJhdGkiOiIwMWVmZmI2MS1jMWMzLTRlYTEtYTA1YS00ZTJhYzdlNWIwNWYiLCJleHAiOjE0ODk2ODI2NjMsImF1dGhvcml0aWVzIjpbIlJPTEVfQURNSU4iXSwianRpIjoiMTQwMDIyMWItN2ViYS00ZTBmLWE3YzEtZjc1ZTdiMzk2Y2FjIiwiY2xpZW50X2lkIjoibXktdHJ1c3RlZC1jbGllbnQifQ.d_jGAEPjXyIsh-sJguOAET-9xxTGx6YJ5Fgu_13RudI","expires_in":119,"scope":"read write whaterver","userNameFromUser":"[email protected]","jti":"01effb61-c1c3-4ea1-a05a-4e2ac7e5b05f"}

I Receive a valid token and as I expected access token is valid for 2 minutes and refresh for an hour.

The decoded refresh token

{
"aud": [
"auth2-resource"
],
"user_name": "XXX",
"scope": [
"read",
"write",
"whaterver"
],
"userNameFromUser": "XXX",
"ati": "01effb61-c1c3-4ea1-a05a-4e2ac7e5b05f",
"exp": 1489682663,
"authorities": [
"ROLE_ADMIN"
],
"jti": "1400221b-7eba-4e0f-a7c1-f75e7b396cac",
"client_id": "my-trusted-client"
}

When I refresh using the refresh token say 1 minute later

curl -v -u my-trusted-client:secret -d "grant_type=refresh_token&client_id=my-trusted-client&refresh_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiYXV0aDItcmVzb3VyY2UiXSwidXNlcl9uYW1lIjoibXIubmlnZ3VAZ21haWwuY29tIiwic2NvcGUiOlsicmVhZCIsIndyaXRlIiwid2hhdGVydmVyIl0sInVzZXJOYW1lRnJvbVVzZXIiOiJtci5uaWdndUBnbWFpbC5jb20iLCJhdGkiOiIwMWVmZmI2MS1jMWMzLTRlYTEtYTA1YS00ZTJhYzdlNWIwNWYiLCJleHAiOjE0ODk2ODI2NjMsImF1dGhvcml0aWVzIjpbIlJPTEVfQURNSU4iXSwianRpIjoiMTQwMDIyMWItN2ViYS00ZTBmLWE3YzEtZjc1ZTdiMzk2Y2FjIiwiY2xpZW50X2lkIjoibXktdHJ1c3RlZC1jbGllbnQifQ.d_jGAEPjXyIsh-sJguOAET-9xxTGx6YJ5Fgu_13RudI"  http://$AUTH_HOST:$AUTH_PORT/$AUTH_CONTEXT/oauth/token

I Receive a new valid access and refresh token

{"access_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiYXV0aDItcmVzb3VyY2UiXSwidXNlcl9uYW1lIjoibXIubmlnZ3VAZ21haWwuY29tIiwic2NvcGUiOlsicmVhZCIsIndyaXRlIiwid2hhdGVydmVyIl0sInVzZXJOYW1lRnJvbVVzZXIiOiJtci5uaWdndUBnbWFpbC5jb20iLCJleHAiOjE0ODk2NzkyMjEsImF1dGhvcml0aWVzIjpbIlJPTEVfQURNSU4iXSwianRpIjoiMmQ3NTRiZmQtNWY3Ni00NDA0LTk2ZDAtMTIwNTM2ZDQyYWM4IiwiY2xpZW50X2lkIjoibXktdHJ1c3RlZC1jbGllbnQifQ.lBJ_-qi4ZS2sCcJAnTK-ydDFwqxgLN88jhSx5nvFJHY","token_type":"bearer","refresh_token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOlsiYXV0aDItcmVzb3VyY2UiXSwidXNlcl9uYW1lIjoibXIubmlnZ3VAZ21haWwuY29tIiwic2NvcGUiOlsicmVhZCIsIndyaXRlIiwid2hhdGVydmVyIl0sInVzZXJOYW1lRnJvbVVzZXIiOiJtci5uaWdndUBnbWFpbC5jb20iLCJhdGkiOiIyZDc1NGJmZC01Zjc2LTQ0MDQtOTZkMC0xMjA1MzZkNDJhYzgiLCJleHAiOjE0ODk2ODI2NjMsImF1dGhvcml0aWVzIjpbIlJPTEVfQURNSU4iXSwianRpIjoiMTQwMDIyMWItN2ViYS00ZTBmLWE3YzEtZjc1ZTdiMzk2Y2FjIiwiY2xpZW50X2lkIjoibXktdHJ1c3RlZC1jbGllbnQifQ.ximnk1WW9WBx4TW3WuQyNMbgZlUXlMHC6k9Hdjy_-4A","expires_in":119,"scope":"read write whaterver","userNameFromUser":"XXX","jti":"2d754bfd-5f76-4404-96d0-120536d42ac8"}

The decoded new access token has the same exp as the first one:

{
"aud": [
"auth2-resource"
],
"user_name": "XXX",
"scope": [
"read",
"write",
"whaterver"
],
"userNameFromUser": "XXX",
"ati": "2d754bfd-5f76-4404-96d0-120536d42ac8",
"exp": 1489682663,
"authorities": [
"ROLE_ADMIN"
],
"jti": "1400221b-7eba-4e0f-a7c1-f75e7b396cac",
"client_id": "my-trusted-client"
}

But the access token is now about to be expired in the next minute and I expected it to valid for another 2 minutes from the moment the refresh happened.

As you may see in the exp of the refresh token, it is the same after the refresh. That's not the case for the access token.

I thought that I could set an expiry of about 2 minutes to the refresh token, and every time i refresh I would have another 2 minutes. But that's not the case.

I would expect a user only giving his credentials at login and then as long as he is working (and refreshing tokens in background) he should not be forced to login again. But at the moment this is not the case. Since he is logged out after the last successfull refresh of the token plus the expiry of access token.

Am I missing something? What's wrong? Any help or suggestions welcome. Thanx in advance.

like image 641
Nicolas Schwarzentrub Avatar asked Mar 16 '17 16:03

Nicolas Schwarzentrub


1 Answers

Ok I can see that you set the reuseRefreshToken flag of the DefaultTokenServices to false, but do you actually use this bean in the Authorization server? I bet you don't and that is the reason why the validity period of the refresh token is not renewed. In order to use this bean in the authorization server you must exclusively declare it in the AuthorizationServerEndpointsConfigurer as in :

public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception { 
           endpoints.tokenServices(youTokenServicesBean)
}

otherwise a DefaultTokenServices instance created by the AuthorizationServerEndpointsConfigurer will be used in the authorization server side, which is in most cases adequate. So in that case, in order to configure the AuthorizationTokenServices to renew the validity period of the token you have to simply add:

public void configure(AuthorizationServerEndpointsConfigurer endpoints) 
throws Exception { 
       endpoints.reuseRefreshTokens(false);
}
like image 72
stelios Avatar answered Jan 04 '23 08:01

stelios