提交 60c4b7a2 编写于 作者: zlt2000's avatar zlt2000

登录同应用同账号互踢

上级 0c85184e
......@@ -4,7 +4,9 @@ import com.central.oauth.granter.MobilePwdGranter;
import com.central.oauth.granter.OpenIdGranter;
import com.central.oauth.granter.PwdImgCodeGranter;
import com.central.oauth.service.IValidateCodeService;
import com.central.oauth.service.impl.CustomTokenServices;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
......@@ -67,6 +69,12 @@ public class TokenGranterConfig {
private TokenGranter tokenGranter;
/**
* 是否登录同应用同账号互踢
*/
@Value("${zlt.uaa.isSingleLogin:false}")
private boolean isSingleLogin;
/**
* 授权模式
*/
......@@ -149,7 +157,7 @@ public class TokenGranterConfig {
}
private DefaultTokenServices createDefaultTokenServices() {
DefaultTokenServices tokenServices = new DefaultTokenServices();
DefaultTokenServices tokenServices = new CustomTokenServices(isSingleLogin);
tokenServices.setTokenStore(tokenStore);
tokenServices.setSupportRefreshToken(true);
tokenServices.setReuseRefreshToken(reuseRefreshToken);
......
package com.central.oauth.service.impl;
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;
/**
* 重写 DefaultTokenServices,实现登录同应用同账号互踢
*
* @author zlt
* @date 2021/1/28
* <p>
* Blog: https://zlt2000.gitee.io
* Github: https://github.com/zlt2000
*/
public class CustomTokenServices extends DefaultTokenServices {
private TokenStore tokenStore;
private TokenEnhancer accessTokenEnhancer;
/**
* 是否登录同应用同账号互踢
*/
private boolean isSingleLogin;
public CustomTokenServices(boolean isSingleLogin) {
this.isSingleLogin = isSingleLogin;
}
@Override
@Transactional
public OAuth2AccessToken createAccessToken(OAuth2Authentication authentication) throws AuthenticationException {
OAuth2AccessToken existingAccessToken = tokenStore.getAccessToken(authentication);
OAuth2RefreshToken refreshToken = null;
if (existingAccessToken != null) {
if (isSingleLogin) {
if (existingAccessToken.getRefreshToken() != null) {
tokenStore.removeRefreshToken(existingAccessToken.getRefreshToken());
}
tokenStore.removeAccessToken(existingAccessToken);
} else if (existingAccessToken.isExpired()) {
if (existingAccessToken.getRefreshToken() != null) {
refreshToken = existingAccessToken.getRefreshToken();
// The token store could remove the refresh token when the
// access token is removed, but we want to
// be sure...
tokenStore.removeRefreshToken(refreshToken);
}
tokenStore.removeAccessToken(existingAccessToken);
}
else {
// Re-store the access token in case the authentication has changed
tokenStore.storeAccessToken(existingAccessToken, authentication);
return existingAccessToken;
}
}
// Only create a new refresh token if there wasn't an existing one
// associated with an expired access token.
// Clients might be holding existing refresh tokens, so we re-use it in
// the case that the old access token
// expired.
if (refreshToken == null) {
refreshToken = createRefreshToken(authentication);
}
// But the refresh token itself might need to be re-issued if it has
// expired.
else if (refreshToken instanceof ExpiringOAuth2RefreshToken) {
ExpiringOAuth2RefreshToken expiring = (ExpiringOAuth2RefreshToken) refreshToken;
if (System.currentTimeMillis() > expiring.getExpiration().getTime()) {
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;
}
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;
}
@Override
public void setTokenStore(TokenStore tokenStore) {
this.tokenStore = tokenStore;
super.setTokenStore(tokenStore);
}
@Override
public void setTokenEnhancer(TokenEnhancer accessTokenEnhancer) {
this.accessTokenEnhancer = accessTokenEnhancer;
super.setTokenEnhancer(accessTokenEnhancer);
}
}
......@@ -32,4 +32,7 @@ zlt:
tenant:
enable: true
ignoreTables:
- oauth_client_details
\ No newline at end of file
- oauth_client_details
#是否登录同应用同账号互踢
uaa:
isSingleLogin: false
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册