问题
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