Spring OAuth2:RefreshTokens的有效期未续订

问题描述 投票:5回答:2

我在后端使用资源所有者密码授权和spring-security-oauth。令牌是JWT。

我想拥有短暂的生活访问权限(比如说2分钟),但需要很长时间的生活刷新代币(比如小时)。

据我了解,在第一次登录后,访问令牌应该有效2分钟,刷新令牌有效1小时。那就是。但就是这样。刷新令牌时,有效性保持不变。似乎密码授权的原始到期仍然有效,并且刷新是某种被忽略的。实际上我得到了一个新令牌,但到期时间与密码授予相同。

    @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;
}

使用密码流登录

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

返回类似的东西:

{"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"}

我收到一个有效的令牌,因为我预期访问令牌有效2分钟,刷新一小时。

已解码的刷新令牌

{
"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"
}

当我使用刷新令牌刷新时说1分钟后

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

我收到一个新的有效访问和刷新令牌

{"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"}

解码后的新访问令牌与第一个令牌具有相同的exp:

{
"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"
}

但是访问令牌现在即将在下一分钟到期,我预计它会在刷新发生的那一刻起再保持2分钟。

正如您在刷新令牌的exp中看到的那样,刷新后它是相同的。访问令牌不是这种情况。

我以为我可以设置约2分钟到刷新令牌的时间,每次刷新我还有2分钟。但事实并非如此。

我希望用户只能在登录时提供他的凭据,然后只要他正在工作(并在后台刷新令牌),他就不应该被迫再次登录。但目前情况并非如此。由于他在最后一次成功刷新令牌以及访问令牌到期后退出。

我错过了什么吗?怎么了?任何帮助或建议欢迎。提前致谢。

oauth-2.0 spring-security-oauth2 spring-oauth2
2个回答
2
投票

好的我可以看到你将DefaultTokenServices的reuseRefreshToken标志设置为false,但是你真的在Authorization服务器中使用了这个bean吗?我打赌你不这样做,这就是更新刷新令牌的有效期没有更新的原因。要在授权服务器中使用此bean,您必须在AuthorizationServerEndpointsConfigurer中专门声明它,如下所示:

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

否则,AuthorizationServerEndpointsConfigurer创建的DefaultTokenServices实例将在授权服务器端使用,这在大多数情况下是足够的。因此,在这种情况下,为了配置AuthorizationTokenServices来更新令牌的有效期,您只需添加:

public void configure(AuthorizationServerEndpointsConfigurer endpoints) 
throws Exception { 
       endpoints.reuseRefreshTokens(false);
}

0
投票

对我来说,有效的是禁止在令牌服务上重用刷新令牌(在我的案例中是DefaultTokenServices)

DefaultTokenServices tokenServices = new DefaultTokenServices();
tokenServices.setClientDetailsService(clientDetailsService);
tokenServices.setTokenStore(tokenStore());
tokenServices.setSupportRefreshToken(true);
tokenServices.setReuseRefreshToken(false);
© www.soinside.com 2019 - 2024. All rights reserved.