楼主这里有这样一个需求:因为同一个客户端在获取token时 判断token是否存在 如果存在 将重新使用这个token 领导需要楼主在每次登陆时都产生新的token 这里我们选择自定义TokenServices
AuthorizationServerConfig(去掉其他配置)
oauth2认证中心的核心配置类为AuthorizationServerConfig
1.重写TokenServices实现生成token的逻辑
2.token是一系列字符加密生成的 通过tokenServices.setTokenEnhancer(tokenEnhancer());指定是由那些字符生成的
@Configuration
@EnableAuthorizationServer // 开启了认证服务器
public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
/**
* token管理方式,在TokenConfig类中已对添加到容器中了
*/
@Autowired
private TokenStore tokenStore;
@Bean
public TokenEnhancer tokenEnhancer() {
return new CustomTokenEnhancer();
}
/**
* 关于认证服务器端点配置
*
* @param endpoints
* @throws Exception
*/
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
// 自定义令牌加强
endpoints.tokenServices(tokenService());
}
@Bean
public CustomDefaultTokenServices tokenService() {
// 重定义了token的生成逻辑
CustomDefaultTokenServices tokenServices = new CustomDefaultTokenServices();
// token持久化容器
tokenServices.setTokenStore(tokenStore);
// 自定义token是由那些字符生成的
tokenServices.setTokenEnhancer(tokenEnhancer());
// access_token 的有效时长 (秒), 默认 12 小时
tokenServices.setAccessTokenValiditySeconds(60 * 60 * 2);
return tokenServices;
}
}
CustomTokenEnhancer
编写CustomTokenEnhancer实现TokenEnhancer 接口 ,由代码可以 token是在原有基础上 加上用户名 访问ip 客户端id等信息
public class CustomTokenEnhancer implements TokenEnhancer {
@Autowired
Utils utils;
/**
* @Description 重新定义令牌token
* @Date 2019/7/9 19:56
* @Version 1.0
*/
@Override
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
if (accessToken instanceof DefaultOAuth2AccessToken) {
DefaultOAuth2AccessToken token = (DefaultOAuth2AccessToken)accessToken;
Map<String, Object> additionalInformation = Maps.newHashMap();
additionalInformation.put("client_id", authentication.getOAuth2Request().getClientId());
additionalInformation.put("client_Ip", utils.getIpAddr());
// 获取用户名
SysUser sysUser = (SysUser)authentication.getPrincipal();
additionalInformation.put("user_name", sysUser.getUsername());
additionalInformation.put("user_id", sysUser.getId());
// 获取浏览器名称
additionalInformation.put("web_name", utils.getWebName());
token.setAdditionalInformation(additionalInformation);
return token;
}
return accessToken;
}
}
在获取token时 可以解析出来token包含的内容
CustomDefaultTokenServices
CustomDefaultTokenServices首先复制默认的defaultTokenServices 并复制到CustomDefaultTokenServices
public class CustomDefaultTokenServices
implements AuthorizationServerTokenServices, ResourceServerTokenServices, ConsumerTokenServices, InitializingBean {
private int refreshTokenValiditySeconds = 2592000;
private int accessTokenValiditySeconds = 43200;
private boolean supportRefreshToken = false;
private boolean reuseRefreshToken = true;
private TokenStore tokenStore;
private ClientDetailsService clientDetailsService;
private TokenEnhancer accessTokenEnhancer;
private AuthenticationManager authenticationManager;
public CustomDefaultTokenServices() {}
@Override
public void afterPropertiesSet() throws Exception {
Assert.notNull(this.tokenStore, "tokenStore must be set");
}
@Override
@Transactional
public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException {
OAuth2AccessToken existingAccessToken = this.tokenStore.getAccessToken(authentication);
OAuth2RefreshToken refreshToken = null;
// 每一次都重新生成token
if (refreshToken == null) {
refreshToken = this.createRefreshToken(authentication);
} else if (refreshToken instanceof ExpiringOAuth2RefreshToken) {
ExpiringOAuth2RefreshToken expiring = (ExpiringOAuth2RefreshToken)refreshToken;
if (System.currentTimeMillis() > expiring.getExpiration().getTime()) {
refreshToken = this.createRefreshToken(authentication);
}
}
OAuth2AccessToken accessToken = this.createAccessToken(authentication, refreshToken);
this.tokenStore.storeAccessToken(accessToken, authentication);
refreshToken = accessToken.getRefreshToken();
if (refreshToken != null) {
this.tokenStore.storeRefreshToken(refreshToken, authentication);
}
return accessToken;
}
@Override
@Transactional(noRollbackFor = {InvalidTokenException.class, InvalidGrantException.class})
public OAuth2AccessToken refreshAccessToken(String refreshTokenValue, TokenRequest tokenRequest)
throws AuthenticationException {
if (!this.supportRefreshToken) {
throw new InvalidGrantException("Invalid refresh token: " + refreshTokenValue);
} else {
OAuth2RefreshToken refreshToken = this.tokenStore.readRefreshToken(refreshTokenValue);
if (refreshToken == null) {
throw new InvalidGrantException("Invalid refresh token: " + refreshTokenValue);
} else {
OAuth2Authentication authentication = this.tokenStore.readAuthenticationForRefreshToken(refreshToken);
if (this.authenticationManager != null && !authentication.isClientOnly()) {
Authentication user = new PreAuthenticatedAuthenticationToken(
authentication.getUserAuthentication(), "", authentication.getAuthorities());
user = this.authenticationManager.authenticate(user);
Object details = authentication.getDetails();
authentication = new OAuth2Authentication(authentication.getOAuth2Request(), user);
authentication.setDetails(details);
}
String clientId = authentication.getOAuth2Request().getClientId();
if (clientId != null && clientId.equals(tokenRequest.getClientId())) {
this.tokenStore.removeAccessTokenUsingRefreshToken(refreshToken);
if (this.isExpired(refreshToken)) {
this.tokenStore.removeRefreshToken(refreshToken);
throw new InvalidTokenException("Invalid refresh token (expired): " + refreshToken);
} else {
authentication = this.createRefreshedAuthentication(authentication, tokenRequest);
if (!this.reuseRefreshToken) {
this.tokenStore.removeRefreshToken(refreshToken);
refreshToken = this.createRefreshToken(authentication);
}
OAuth2AccessToken accessToken = this.createAccessToken(authentication, refreshToken);
this.tokenStore.storeAccessToken(accessToken, authentication);
if (!this.reuseRefreshToken) {
this.tokenStore.storeRefreshToken(accessToken.getRefreshToken(), authentication);
}
return accessToken;
}
} else {
throw new InvalidGrantException("Wrong client for this refresh token: " + refreshTokenValue);
}
}
}
}
@Override
public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
return this.tokenStore.getAccessToken(authentication);
}
private OAuth2Authentication createRefreshedAuthentication(OAuth2Authentication authentication,
TokenRequest request) {
Set<String> scope = request.getScope();
OAuth2Request clientAuth = authentication.getOAuth2Request().refresh(request);
if (scope != null && !scope.isEmpty()) {
Set<String> originalScope = clientAuth.getScope();
if (originalScope == null || !originalScope.containsAll(scope)) {
throw new InvalidScopeException(
"Unable to narrow the scope of the client authentication to " + scope + ".", originalScope);
}
clientAuth = clientAuth.narrowScope(scope);
}
OAuth2Authentication narrowed = new OAuth2Authentication(clientAuth, authentication.getUserAuthentication());
return narrowed;
}
protected boolean isExpired(OAuth2RefreshToken refreshToken) {
if (!(refreshToken instanceof ExpiringOAuth2RefreshToken)) {
return false;
} else {
ExpiringOAuth2RefreshToken expiringToken = (ExpiringOAuth2RefreshToken)refreshToken;
return expiringToken.getExpiration() == null
|| System.currentTimeMillis() > expiringToken.getExpiration().getTime();
}
}
@Override
public OAuth2AccessToken readAccessToken(String accessToken) {
return this.tokenStore.readAccessToken(accessToken);
}
@Override
public OAuth2Authentication loadAuthentication(String accessTokenValue)
throws AuthenticationException, InvalidTokenException {
OAuth2AccessToken accessToken = this.tokenStore.readAccessToken(accessTokenValue);
if (accessToken == null) {
throw new InvalidTokenException("Invalid access token: " + accessTokenValue);
} else if (accessToken.isExpired()) {
this.tokenStore.removeAccessToken(accessToken);
throw new InvalidTokenException("Access token expired: " + accessTokenValue);
} else {
OAuth2Authentication result = this.tokenStore.readAuthentication(accessToken);
if (result == null) {
throw new InvalidTokenException("Invalid access token: " + accessTokenValue);
} else {
if (this.clientDetailsService != null) {
String clientId = result.getOAuth2Request().getClientId();
try {
this.clientDetailsService.loadClientByClientId(clientId);
} catch (ClientRegistrationException var6) {
throw new InvalidTokenException("Client not valid: " + clientId, var6);
}
}
return result;
}
}
}
public String getClientId(String tokenValue) {
OAuth2Authentication authentication = this.tokenStore.readAuthentication(tokenValue);
if (authentication == null) {
throw new InvalidTokenException("Invalid access token: " + tokenValue);
} else {
OAuth2Request clientAuth = authentication.getOAuth2Request();
if (clientAuth == null) {
throw new InvalidTokenException("Invalid access token (no client id): " + tokenValue);
} else {
return clientAuth.getClientId();
}
}
}
@Override
public boolean revokeToken(String tokenValue) {
OAuth2AccessToken accessToken = this.tokenStore.readAccessToken(tokenValue);
if (accessToken == null) {
return false;
} else {
if (accessToken.getRefreshToken() != null) {
this.tokenStore.removeRefreshToken(accessToken.getRefreshToken());
}
this.tokenStore.removeAccessToken(accessToken);
return true;
}
}
private OAuth2RefreshToken createRefreshToken(OAuth2Authentication authentication) {
if (!this.isSupportRefreshToken(authentication.getOAuth2Request())) {
return null;
} else {
int validitySeconds = this.getRefreshTokenValiditySeconds(authentication.getOAuth2Request());
String value = UUID.randomUUID().toString();
return (OAuth2RefreshToken)(validitySeconds > 0
? new DefaultExpiringOAuth2RefreshToken(value,
new Date(System.currentTimeMillis() + (long)validitySeconds * 1000L))
: new DefaultOAuth2RefreshToken(value));
}
}
private OAuth2AccessToken createAccessToken(OAuth2Authentication authentication, OAuth2RefreshToken refreshToken) {
DefaultOAuth2AccessToken token = new DefaultOAuth2AccessToken(UUID.randomUUID().toString());
int validitySeconds = this.getAccessTokenValiditySeconds(authentication.getOAuth2Request());
if (validitySeconds > 0) {
token.setExpiration(new Date(System.currentTimeMillis() + (long)validitySeconds * 1000L));
}
token.setRefreshToken(refreshToken);
token.setScope(authentication.getOAuth2Request().getScope());
return (OAuth2AccessToken)(this.accessTokenEnhancer != null
? this.accessTokenEnhancer.enhance(token, authentication) : token);
}
protected int getAccessTokenValiditySeconds(OAuth2Request clientAuth) {
if (this.clientDetailsService != null) {
ClientDetails client = this.clientDetailsService.loadClientByClientId(clientAuth.getClientId());
Integer validity = client.getAccessTokenValiditySeconds();
if (validity != null) {
return validity;
}
}
return this.accessTokenValiditySeconds;
}
protected int getRefreshTokenValiditySeconds(OAuth2Request clientAuth) {
if (this.clientDetailsService != null) {
ClientDetails client = this.clientDetailsService.loadClientByClientId(clientAuth.getClientId());
Integer validity = client.getRefreshTokenValiditySeconds();
if (validity != null) {
return validity;
}
}
return this.refreshTokenValiditySeconds;
}
protected boolean isSupportRefreshToken(OAuth2Request clientAuth) {
if (this.clientDetailsService != null) {
ClientDetails client = this.clientDetailsService.loadClientByClientId(clientAuth.getClientId());
return client.getAuthorizedGrantTypes().contains("refresh_token");
} else {
return this.supportRefreshToken;
}
}
public void setTokenEnhancer(TokenEnhancer accessTokenEnhancer) {
this.accessTokenEnhancer = accessTokenEnhancer;
}
public void setRefreshTokenValiditySeconds(int refreshTokenValiditySeconds) {
this.refreshTokenValiditySeconds = refreshTokenValiditySeconds;
}
public void setAccessTokenValiditySeconds(int accessTokenValiditySeconds) {
this.accessTokenValiditySeconds = accessTokenValiditySeconds;
}
public void setSupportRefreshToken(boolean supportRefreshToken) {
this.supportRefreshToken = supportRefreshToken;
}
public void setReuseRefreshToken(boolean reuseRefreshToken) {
this.reuseRefreshToken = reuseRefreshToken;
}
public void setTokenStore(TokenStore tokenStore) {
this.tokenStore = tokenStore;
}
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
public void setClientDetailsService(ClientDetailsService clientDetailsService) {
this.clientDetailsService = clientDetailsService;
}
}
修改的核心代码
这里只修改了每一次都生成新token
@Override
@Transactional
public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException {
OAuth2AccessToken existingAccessToken = this.tokenStore.getAccessToken(authentication);
OAuth2RefreshToken refreshToken = null;
// 每一次都重新生成token
if (refreshToken == null) {
refreshToken = this.createRefreshToken(authentication);
} else if (refreshToken instanceof ExpiringOAuth2RefreshToken) {
ExpiringOAuth2RefreshToken expiring = (ExpiringOAuth2RefreshToken)refreshToken;
if (System.currentTimeMillis() > expiring.getExpiration().getTime()) {
refreshToken = this.createRefreshToken(authentication);
}
}
OAuth2AccessToken accessToken = this.createAccessToken(authentication, refreshToken);
this.tokenStore.storeAccessToken(accessToken, authentication);
refreshToken = accessToken.getRefreshToken();
if (refreshToken != null) {
this.tokenStore.storeRefreshToken(refreshToken, authentication);
}
return accessToken;
}
然后在AuthorizationServerConfig 中 按照楼主的配置即可。