Spring Security OAuth2: Purge TokenStore

走远了吗. 提交于 2020-08-05 19:28:14

问题


Is there any way to configure Spring Security OAuth2 so it automatically purge TokenStore?

I want to remove the expired tokens from time to time. I've seen the InMemoryTokenStore code and it performs a flush every now and again.

But JdbcTokenStore does not perform any purge, so Who is in charge of removing the expried tokens from the storage?

I've implemented a TokenStore that uses MongoDB as storage, but I have the same problem. Nobody is removing the expired tokens from the storage.


回答1:


Unfortunately, JdbcTokenStore does not purge expired tokens automatically. It's up to you to purge old tokens. Here's an idea how I would add such a mechanism.

Expiration date is part of OAuth2AccessToken which gets persisted as a serialized java object in the database. In order to detect whether an OAuth2AccessToken is eligible for deletion you would need to read it from the database an deserialize it. This may lead to performance penalties where you need to purge a high amount of OAuth2AccessTokens.

My suggestion is to expand oauth_access_token table by a column expiration of type TIMESTAMP (H2 dialect) for saving expiration date.

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
);

Extend JdbcTokenStore and override storeAccessToken method. Don't forget to alter insertAccessTokenSql in order to honor new column expiration in the insert statement.

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 });
}

Enable Spring's Task Execution and Scheduling and add a scheduled method which purges old tokens.

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

Caution. This code just demonstrates my idea. I can't guarantee that there are no errors. Your code may and should vary from my example code.



来源:https://stackoverflow.com/questions/30617554/spring-security-oauth2-purge-tokenstore

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!