com.healthy.security.server.HealthyTokenServices Maven / Gradle / Ivy
package com.healthy.security.server;
import com.healthy.security.server.kickout.KickOutPostProcessor;
import com.healthy.security.server.kickout.impl.DefaultKickOutPostProcessor;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.oauth2.common.*;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.token.DefaultTokenServices;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.UUID;
/**
* Base implementation for token services using random UUID values for the access token
* and refresh token values. The main extension point for customizations is the
* {@link TokenEnhancer} which will be called after the access and refresh tokens have
* been generated but before they are stored.
*
* Persistence is delegated to a {@code TokenStore} implementation and customization of
* the access token to a {@link TokenEnhancer}.
*
* @author xiaomingzhang
*/
public class HealthyTokenServices extends DefaultTokenServices {
private boolean kickOut = false;
private TokenStore tokenStore;
private TokenEnhancer accessTokenEnhancer;
private KickOutPostProcessor kickOutPostProcessor = new DefaultKickOutPostProcessor();
@Override
@Transactional
public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException {
if (kickOut) {
OAuth2AccessToken existingAccessToken = tokenStore.getAccessToken(authentication);
if (existingAccessToken != null) {
tokenStore.removeAccessToken(existingAccessToken);
kickOutPostProcessor.onPostProcess(authentication, existingAccessToken);
}
OAuth2RefreshToken refreshToken = createRefreshToken(authentication);
OAuth2AccessToken accessToken = createAccessToken(authentication, refreshToken);
tokenStore.storeAccessToken(accessToken, authentication);
// In case it was modified
refreshToken = accessToken.getRefreshToken();
if (refreshToken != null) {
tokenStore.storeRefreshToken(refreshToken, authentication);
}
return accessToken;
}
else {
return super.createAccessToken(authentication);
}
}
private OAuth2RefreshToken createRefreshToken(OAuth2Authentication authentication) {
if (!isSupportRefreshToken(authentication.getOAuth2Request())) {
return null;
}
int validitySeconds = getRefreshTokenValiditySeconds(authentication.getOAuth2Request());
String value = UUID.randomUUID().toString();
if (validitySeconds > 0) {
return new DefaultExpiringOAuth2RefreshToken(value,
new Date(System.currentTimeMillis() + (validitySeconds * 1000L)));
}
return new DefaultOAuth2RefreshToken(value);
}
private OAuth2AccessToken createAccessToken(OAuth2Authentication authentication, OAuth2RefreshToken refreshToken) {
DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(UUID.randomUUID().toString());
int validitySeconds = getAccessTokenValiditySeconds(authentication.getOAuth2Request());
if (validitySeconds > 0) {
token.setExpiration(new Date(System.currentTimeMillis() + (validitySeconds * 1000L)));
}
token.setRefreshToken(refreshToken);
token.setScope(authentication.getOAuth2Request().getScope());
return accessTokenEnhancer != null ? accessTokenEnhancer.enhance(token, authentication) : token;
}
/**
* The persistence strategy for token storage.
* @param tokenStore the store for access and refresh tokens.
*/
@Override
public void setTokenStore(TokenStore tokenStore) {
super.setTokenStore(tokenStore);
this.tokenStore = tokenStore;
}
/**
* An access token enhancer that will be applied to a new token before it is saved in
* the token store.
* @param accessTokenEnhancer the access token enhancer to set
*/
@Override
public void setTokenEnhancer(TokenEnhancer accessTokenEnhancer) {
super.setTokenEnhancer(accessTokenEnhancer);
this.accessTokenEnhancer = accessTokenEnhancer;
}
/**
* Log in and kick out .
* @param kickOut Whether to support login and kick out.
*/
public void setKickOut(boolean kickOut) {
this.kickOut = kickOut;
}
/**
* Set the kick-out post processor
* @param kickOutPostProcessor kick-out post processor
*/
public void setKickOutPostProcessor(KickOutPostProcessor kickOutPostProcessor) {
this.kickOutPostProcessor = kickOutPostProcessor;
}
}