SpringSecurity oauth2.0 token自动续期
一、token 续期
spring security oauth2.0 默认 token 生成机制是没有为token 失效自动续期的。
用户token保存在redis 缓存服务器。
例如设置token 失效日期为7天,那么无论这7天用户做了操作或者没有做操作token 都会失效
针对这个问题解决办法有两个:
1. app端 在token 失效时调用oauth2.0 refresh_token 接口主动刷新token接口实现token续期
2. app用户每次访问接口时,通过代码动态重置token失效时间(模拟Web 服务器 Session机制)
新建自定义 AutoRenewalRedisTokenStore 实现类
public class AutoRenewalRedisTokenStore extends RedisTokenStore {
private ClientDetailsServiceclientDetailsService;
public AutoRenewalRedisTokenStore(RedisConnectionFactory connectionFactory, ClientDetailsService clientDetailsService) {
super(connectionFactory);
this.clientDetailsService = clientDetailsService;
}
@Override
public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
OAuth2Authentication result = readAuthentication(token.getValue());
if (result !=null) {
DefaultOAuth2AccessToken oAuth2AccessToken = (DefaultOAuth2AccessToken) token;
int validitySeconds = getAccessTokenValiditySeconds(result.getOAuth2Request());
if (validitySeconds >0) {
oAuth2AccessToken.setExpiration(new Date(validitySeconds *1000L));
}
storeAccessToken(token, result);
}
return result;
}
protected int getAccessTokenValiditySeconds(OAuth2Request clientAuth) {
if (clientDetailsService !=null) {
ClientDetails client =clientDetailsService.loadClientByClientId(clientAuth.getClientId());
Integer validity = client.getAccessTokenValiditySeconds();
if (validity !=null) {
return validity;
}
}
int accessTokenValiditySeconds =60 *60 *24 *7;
return accessTokenValiditySeconds;
}
}
用户授权认证配置时设置redis token 存储方案
基于OAUTH2.0 用户认证服务器
@Configuration
@AllArgsConstructor
@EnableAuthorizationServer
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
private final DataSourcedataSource;
private final ClientDetailsServiceclientDetailsService;
private final TokenEnhancerdefaultTokenEnhancer;
private final CustomUserDetailsServicecustomUserDetailsService;
private final AuthenticationManagerauthenticationManagerBean;
private final RedisConnectionFactoryredisConnectionFactory;
@Override
@SneakyThrows
public void configure(ClientDetailsServiceConfigurer clients) {
CacheClientDetailsService clientDetailsService =new CacheClientDetailsService(dataSource);
clientDetailsService.setSelectClientDetailsSql(SecurityConstants.DEFAULT_SELECT_STATEMENT);
clientDetailsService.setFindClientDetailsSql(SecurityConstants.DEFAULT_FIND_STATEMENT);
clients.withClientDetails(clientDetailsService);
}
@Override
public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
oauthServer
.allowFormAuthenticationForClients()
.checkTokenAccess(“isAuthenticated()”);
}
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
endpoints
.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST)
.tokenStore(tokenStore())
.tokenEnhancer(defaultTokenEnhancer)
.userDetailsService(customUserDetailsService)
.authenticationManager(authenticationManagerBean)
.reuseRefreshTokens(false)
.exceptionTranslator(new WebResponseExceptionTranslatorImpl());
}
@Bean
public TokenStore tokenStore() {
//RedisTokenStore tokenStore = new RedisTokenStore(redisConnectionFactory);
AutoRenewalRedisTokenStore tokenStore =new AutoRenewalRedisTokenStore(redisConnectionFactory,clientDetailsService);
return tokenStore;
}
}