Spring OAuth2 token自动续签方案

环境说明

我使用的是Spring Cloud OAuth2, 并使用的Redis做的token存储方案, 实现了使用 access_token 每次访问系统接口的时候刷新token的过期时间

另外这只是我自己个人琢磨的一套方案, 如果有大神有什么想法欢迎指教

如果有其他token存储方案的应该也类似, 不说了直接上代码

自定义TokenStoreService

public class MyRedisTokenStoreService extends RedisTokenStore {
	private ClientDetailsService clientDetailsService;

	public MyRedisTokenStoreService(RedisConnectionFactory connectionFactory, ClientDetailsService clientDetailsService) {
		super(connectionFactory);
		this.clientDetailsService = clientDetailsService;
	}

	@Override
	public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
		OAuth2Authentication result = readAuthentication(token.getValue());
		if (result != null) {
			// 如果token没有失效  更新AccessToken过期时间
			DefaultOAuth2AccessToken oAuth2AccessToken = (DefaultOAuth2AccessToken) token;

			//重新设置过期时间
			int validitySeconds = getAccessTokenValiditySeconds(result.getOAuth2Request());
			if (validitySeconds > 0) {
				oAuth2AccessToken.setExpiration(new Date(System.currentTimeMillis() + (validitySeconds * 1000L)));
			}

			//将重新设置过的过期时间重新存入redis, 此时会覆盖redis中原本的过期时间
			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;
			}
		}
		// default 12 hours.
		int accessTokenValiditySeconds = 60 * 60 * 12;
		return accessTokenValiditySeconds;
	}
}

复制代码

tokenStoreConfig

@Configuration
public class TokenStoreConfig {
	private final RedisConnectionFactory redisConnectionFactory;
	private final ClientDetailsService clientDetailsService;

	@Autowired
	public TokenStoreConfig(RedisConnectionFactory redisConnectionFactory, ClientDetailsService clientDetailsService) {
		this.redisConnectionFactory = redisConnectionFactory;
		this.clientDetailsService = clientDetailsService;
	}

	/**
	 * havingValue 当name的值与此值相同时加载配置
	 * @return
	 */
	@Bean
	public TokenStore redisTokenStore() {
		MyRedisTokenStoreService tokenStoreService = new MyRedisTokenStoreService(redisConnectionFactory, clientDetailsService);
		tokenStoreService.setPrefix("user-token:");
		return tokenStoreService;
	}
}
复制代码
分类:
后端
标签: