Spring Security OAuth2:清除 TokenStore

jfc*_*edo 2 spring oauth spring-security oauth-2.0 spring-security-oauth2

有什么方法可以配置 Spring Security OAuth2 使其自动清除 TokenStore?

我想不时删除过期的令牌。我见过 InMemoryTokenStore 代码,它不时执行刷新。

但是 JdbcTokenStore 不执行任何清除,那么谁负责从存储中删除过期的令牌?

我已经实现了一个使用 MongoDB 作为存储的 TokenStore,但我遇到了同样的问题。没有人从存储中删除过期的令牌。

Kam*_*kol 5

不幸的是,JdbcTokenStore不会自动清除过期的令牌。清除旧令牌取决于您。这是我如何添加这样一个机制的想法。

Expiration date是其中的一部分OAuth2AccessToken作为数据库中的序列化 java 对象持久化。为了检测一个OAuth2AccessToken是否符合删除条件,您需要从数据库中读取它并对其进行反序列化。这可能会导致性能下降,您需要清除大量 OAuth2AccessToken。

我的建议是oauth_access_tokenexpiration类型TIMESTAMP(H2 方言)的列扩展表以保存到期日期。

create table oauth_access_token (
  token_id VARCHAR(256),
  token LONGVARBINARY,
  authentication_id VARCHAR(256),
  user_name VARCHAR(256),
  client_id VARCHAR(256),
  authentication LONGVARBINARY,
  refresh_token VARCHAR(256),
  expiration TIMESTAMP
);
Run Code Online (Sandbox Code Playgroud)

扩展JdbcTokenStore和覆盖storeAccessToken方法。不要忘记更改insertAccessTokenSql以支持expiration插入语句中的新列。

public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
    String refreshToken = null;
    if (token.getRefreshToken() != null) {
        refreshToken = token.getRefreshToken().getValue();
    }

    if (readAccessToken(token.getValue())!=null) {
        removeAccessToken(token.getValue());
    }

    jdbcTemplate.update(insertAccessTokenSql, new Object[] { extractTokenKey(token.getValue()),
            new SqlLobValue(serializeAccessToken(token)), authenticationKeyGenerator.extractKey(authentication),
            authentication.isClientOnly() ? null : authentication.getName(),
            authentication.getOAuth2Request().getClientId(),
            new SqlLobValue(serializeAuthentication(authentication)), extractTokenKey(refreshToken), token.getExpiration() }, new int[] {
            Types.VARCHAR, Types.BLOB, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.BLOB, Types.VARCHAR, Types.TIMESTAMP });
}
Run Code Online (Sandbox Code Playgroud)

启用 Spring 的任务执行和调度并添加清除旧令牌的调度方法。

@Scheduled(fixedRate = 10000)
public void purgeOldTokens() {
    java.util.Date now = new Date();
    jdbcTemplate.update("delete from oauth_access_token where expiration <?", now);
}
Run Code Online (Sandbox Code Playgroud)

警告。这段代码只是展示了我的想法。我不能保证没有错误。您的代码可能并且应该与我的示例代码有所不同。