Spring oauth2.0 刷新token后设置原token5分钟内继续可用

默认情况下刷新token后原token会立马不可用。但是在某些情况下我们需要刷新token后原token在一定时间内继续可用(例如微信的刷新token)。

通过查看DefaultTokenServices中的刷新token方法refreshAccessToken可以看到生成新的token后会调用removeAccessTokenUsingRefreshToken方法,此方法默认会删除存储的相关token信息

private void removeAccessTokenUsingRefreshToken(String refreshToken) {
		byte[] key = serializeKey(REFRESH_TO_ACCESS + refreshToken);
		List results = null;
		RedisConnection conn = getConnection();
		try {
			conn.openPipeline();
			conn.get(key);
			conn.del(key);
			results = conn.closePipeline();
		} finally {
			conn.close();
		}
		if (results == null) {
			return;
		}
		byte[] bytes = (byte[]) results.get(0);
		String accessToken = deserializeString(bytes);
		if (accessToken != null) {
			removeAccessToken(accessToken);
		}
	}
 
  

所以就需要重写该方法设置不立即删除

 

首先需要自定义tokenStore

public class OAuth2AuthorizationConfiguration extends AuthorizationServerConfigurerAdapter {
    @Override
	public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
		endpoints.accessTokenConverter(new FrameworkAccessTokenConverter());
		endpoints.authorizationCodeServices(meiceAuthorizationCodeService)
				.tokenEnhancer(jwtAccessTokenConverter())
				.reuseRefreshTokens(false)
                // 使用自定义tokenStore管理tongken
				.tokenStore(meiceTokenStore)
				.userDetailsService(meiceUserDetailsService)
				.authenticationManager(authenticationManager)
				.setClientDetailsService(meiceClientDetailsService);
		endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST);
		endpoints.exceptionTranslator(new MeiceWebResponseExceptionTranslator());
		//使用自定义granter以返回refresh_token.(默认granter不返回)
		endpoints.tokenGranter(new CompositeTokenGranter(getMeiceTokenGranters()));
	}
}
//自定义tokenStore(其他代码参考org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore)
public class IRedisTokenStore implements TokenStore {
    @Override
	public void removeAccessTokenUsingRefreshToken(OAuth2RefreshToken refreshToken) {
		removeAccessTokenUsingRefreshToken(refreshToken.getValue());
	}

	private void removeAccessTokenUsingRefreshToken(String refreshToken) {
		String token = (String) this.redisTemplate.opsForValue().get(REFRESH_TO_ACCESS + refreshToken);

		if (token != null) {
			//设置刷新后5分钟内继续可用
			redisTemplate.expire(ACCESS + token, 300, TimeUnit.SECONDS);
		}
	}
}

至此Token将在刷新后5分钟过期删除.

你可能感兴趣的:(Oauth2.0,oauth)