I have set up an OAuth2 client-credentials flow with a Spring Security Authorization Server (org.springframework.security:spring-security-oauth2-authorization-server:0.2.0) and a standard setup taken from this tutorial that I extended by a database layer. I have one resource server, one client application with multiple clients and the authorization server. Everything works perfectly except for the point that expired tokens keep stacking up in my database.
I defined a RegisteredClientRepository-bean using the JdbcRegisteredClientRepository for my clients and a OAuth2AuthorizationService-bean using the JdbcOAuth2AuthorizationService for the authorizations. My tokens expire after five minutes and the client requests a new token. The OAuth2Authorization entities containing the token remain in the database and I don't find a way to get them cleaned up.
So the OAuth2AuthorizationService can remove authorizations with remove(OAuth2Authorization authorization) and also has a findById(String id) method that gives you the authorization but these are generated UUIDs that I don't know. So I have no way of obtaining the authorization that I want to delete. There is no findAll() method or anything in this direction.
What am I overlooking here? Does Spring have a cleanup job? Is this somehow configurable or something else that I don't know of?
Best regards
EDIT:
I helped myself out by writing custom sql that is scheduled with a cron once a day. This is a lean solution but has the disadvantage that I now depend on the database (postgres uses NOW() but other databases may not) and the table structure from spring. I extended the JdbcOAuth2AuthorizationService to have the code close to where the other database operations are done and the original table name is found. This class is exposed as a OAuth2AuthorizationService-bean.
kotlin:
class ExpiredTokenDeletingOAuth2AuthorizationService(jdbcOperations: JdbcOperations, registeredClientRepository: RegisteredClientRepository)
: JdbcOAuth2AuthorizationService(jdbcOperations, registeredClientRepository) {
val REMOVE_AUTHORIZATION_SQL = "delete from oauth2_authorization where access_token_expires_at < NOW();"
@Scheduled(cron = "0 0 0 * * *")
fun removeExpiredAuthorizations() {
jdbcOperations.update(REMOVE_AUTHORIZATION_SQL)
}
}
But I still suppose there is a better way...