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;

}

}

 转自:https://www.jianshu.com/p/c98c300ee5da