diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfig.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfig.java
index efd29d31e..60a35b468 100644
--- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfig.java
+++ b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/config/AuthorizationServerConfig.java
@@ -19,11 +19,7 @@
package com.pig4cloud.pigx.auth.config;
-import cn.hutool.core.util.StrUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
-import com.pig4cloud.pigx.auth.service.PigxRedisTokenStore;
-import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
-import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
import com.pig4cloud.pigx.common.security.component.PigxCommenceAuthExceptionEntryPoint;
import com.pig4cloud.pigx.common.security.component.PigxWebResponseExceptionTranslator;
import lombok.AllArgsConstructor;
@@ -38,10 +34,9 @@ import org.springframework.security.oauth2.config.annotation.web.configuration.E
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.ClientDetailsService;
-import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.security.oauth2.provider.code.AuthorizationCodeServices;
-import org.springframework.security.oauth2.provider.token.DefaultAuthenticationKeyGenerator;
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
+import org.springframework.security.oauth2.provider.token.TokenStore;
/**
* @author lengleng
@@ -60,9 +55,9 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
private final AuthorizationCodeServices authorizationCodeServices;
- private final PigxRedisTokenStore redisTokenStore;
+ private final TokenStore redisTokenStore;
- private final TokenEnhancer pigxTokenEnhancer;
+ private final TokenEnhancer tokenEnhancer;
private final ObjectMapper objectMapper;
@@ -81,19 +76,8 @@ public class AuthorizationServerConfig extends AuthorizationServerConfigurerAdap
@Override
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
- // 设置tokenStore 前缀相关
- String prefix = String.format(":%s%s", SecurityConstants.PIGX_PREFIX, SecurityConstants.OAUTH_PREFIX);
- redisTokenStore.setPrefix(prefix);
- // 设置区分key 条件
- redisTokenStore.setAuthenticationKeyGenerator(new DefaultAuthenticationKeyGenerator() {
- @Override
- public String extractKey(OAuth2Authentication authentication) {
- return super.extractKey(authentication) + StrUtil.COLON + TenantContextHolder.getTenantId();
- }
- });
-
endpoints.allowedTokenEndpointRequestMethods(HttpMethod.GET, HttpMethod.POST).tokenStore(redisTokenStore)
- .tokenEnhancer(pigxTokenEnhancer).userDetailsService(pigxUserDetailsService)
+ .tokenEnhancer(tokenEnhancer).userDetailsService(pigxUserDetailsService)
.authorizationCodeServices(authorizationCodeServices).authenticationManager(authenticationManagerBean)
.reuseRefreshTokens(false).pathMapping("/oauth/confirm_access", "/token/confirm_access")
.exceptionTranslator(new PigxWebResponseExceptionTranslator());
diff --git a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/service/PigxRedisTokenStore.java b/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/service/PigxRedisTokenStore.java
deleted file mode 100644
index 28a725d95..000000000
--- a/pigx-auth/src/main/java/com/pig4cloud/pigx/auth/service/PigxRedisTokenStore.java
+++ /dev/null
@@ -1,502 +0,0 @@
-package com.pig4cloud.pigx.auth.service;
-
-import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
-import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
-import org.springframework.data.redis.connection.RedisConnection;
-import org.springframework.data.redis.connection.RedisConnectionFactory;
-import org.springframework.data.redis.connection.RedisStringCommands;
-import org.springframework.data.redis.core.Cursor;
-import org.springframework.data.redis.core.ScanOptions;
-import org.springframework.data.redis.core.types.Expiration;
-import org.springframework.security.oauth2.common.ExpiringOAuth2RefreshToken;
-import org.springframework.security.oauth2.common.OAuth2AccessToken;
-import org.springframework.security.oauth2.common.OAuth2RefreshToken;
-import org.springframework.security.oauth2.provider.OAuth2Authentication;
-import org.springframework.security.oauth2.provider.token.AuthenticationKeyGenerator;
-import org.springframework.security.oauth2.provider.token.DefaultAuthenticationKeyGenerator;
-import org.springframework.security.oauth2.provider.token.TokenStore;
-import org.springframework.security.oauth2.provider.token.store.redis.JdkSerializationStrategy;
-import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStore;
-import org.springframework.security.oauth2.provider.token.store.redis.RedisTokenStoreSerializationStrategy;
-import org.springframework.stereotype.Service;
-import org.springframework.util.ClassUtils;
-import org.springframework.util.ReflectionUtils;
-
-import java.lang.reflect.Method;
-import java.util.*;
-
-/**
- * @author lengleng
- * @date 2020/9/3
- *
- * 重写默认tokenStore 保存 username and token 关系
- */
-@Service
-public class PigxRedisTokenStore implements TokenStore {
-
- private static final String ACCESS = "access:";
-
- private static final String AUTH_TO_ACCESS = "auth_to_access:";
-
- private static final String AUTH = "auth:";
-
- private static final String REFRESH_AUTH = "refresh_auth:";
-
- private static final String ACCESS_TO_REFRESH = "access_to_refresh:";
-
- private static final String REFRESH = "refresh:";
-
- private static final String REFRESH_TO_ACCESS = "refresh_to_access:";
-
- private static final String CLIENT_ID_TO_ACCESS = "client_id_to_access:";
-
- private static final String UNAME_TO_ACCESS = "uname_to_access:";
-
- private static final boolean springDataRedis_2_0 = ClassUtils.isPresent(
- "org.springframework.data.redis.connection.RedisStandaloneConfiguration",
- RedisTokenStore.class.getClassLoader());
-
- private final RedisConnectionFactory connectionFactory;
-
- private AuthenticationKeyGenerator authenticationKeyGenerator = new DefaultAuthenticationKeyGenerator();
-
- private RedisTokenStoreSerializationStrategy serializationStrategy = new JdkSerializationStrategy();
-
- private String prefix = "";
-
- private Method redisConnectionSet_2_0;
-
- public PigxRedisTokenStore(RedisConnectionFactory connectionFactory) {
- this.connectionFactory = connectionFactory;
- if (springDataRedis_2_0) {
- this.loadRedisConnectionMethods_2_0();
- }
- }
-
- private static String getApprovalKey(OAuth2Authentication authentication) {
- String userName = authentication.getUserAuthentication() == null ? ""
- : authentication.getUserAuthentication().getName();
- return getApprovalKey(authentication.getOAuth2Request().getClientId(), userName);
- }
-
- private static String getApprovalKey(String clientId, String userName) {
- return clientId + (userName == null ? "" : ":" + userName);
- }
-
- public void setAuthenticationKeyGenerator(AuthenticationKeyGenerator authenticationKeyGenerator) {
- this.authenticationKeyGenerator = authenticationKeyGenerator;
- }
-
- public void setSerializationStrategy(RedisTokenStoreSerializationStrategy serializationStrategy) {
- this.serializationStrategy = serializationStrategy;
- }
-
- public void setPrefix(String prefix) {
- this.prefix = prefix;
- }
-
- private void loadRedisConnectionMethods_2_0() {
- this.redisConnectionSet_2_0 = ReflectionUtils.findMethod(RedisConnection.class, "set", byte[].class,
- byte[].class);
- }
-
- private RedisConnection getConnection() {
- return connectionFactory.getConnection();
- }
-
- private byte[] serialize(Object object) {
- return serializationStrategy.serialize(object);
- }
-
- // 增加key 的多租户区分
- private byte[] serializeKey(String object) {
- return serialize(TenantContextHolder.getTenantId() + prefix + object);
- }
-
- private OAuth2AccessToken deserializeAccessToken(byte[] bytes) {
- return serializationStrategy.deserialize(bytes, OAuth2AccessToken.class);
- }
-
- private OAuth2Authentication deserializeAuthentication(byte[] bytes) {
- return serializationStrategy.deserialize(bytes, OAuth2Authentication.class);
- }
-
- private OAuth2RefreshToken deserializeRefreshToken(byte[] bytes) {
- return serializationStrategy.deserialize(bytes, OAuth2RefreshToken.class);
- }
-
- private byte[] serialize(String string) {
- return serializationStrategy.serialize(string);
- }
-
- private String deserializeString(byte[] bytes) {
- return serializationStrategy.deserializeString(bytes);
- }
-
- @Override
- public OAuth2AccessToken getAccessToken(OAuth2Authentication authentication) {
- String key = authenticationKeyGenerator.extractKey(authentication);
- byte[] serializedKey = serializeKey(AUTH_TO_ACCESS + key);
- byte[] bytes;
- RedisConnection conn = getConnection();
- try {
- bytes = conn.get(serializedKey);
- }
- finally {
- conn.close();
- }
- OAuth2AccessToken accessToken = deserializeAccessToken(bytes);
- if (accessToken != null) {
- OAuth2Authentication storedAuthentication = readAuthentication(accessToken.getValue());
- if ((storedAuthentication == null
- || !key.equals(authenticationKeyGenerator.extractKey(storedAuthentication)))) {
- // Keep the stores consistent (maybe the same user is
- // represented by this authentication but the details have
- // changed)
- storeAccessToken(accessToken, authentication);
- }
-
- }
- return accessToken;
- }
-
- @Override
- public OAuth2Authentication readAuthentication(OAuth2AccessToken token) {
- return readAuthentication(token.getValue());
- }
-
- @Override
- public OAuth2Authentication readAuthentication(String token) {
- byte[] bytes = null;
- RedisConnection conn = getConnection();
- try {
- bytes = conn.get(serializeKey(AUTH + token));
- }
- finally {
- conn.close();
- }
- OAuth2Authentication auth = deserializeAuthentication(bytes);
- return auth;
- }
-
- @Override
- public OAuth2Authentication readAuthenticationForRefreshToken(OAuth2RefreshToken token) {
- return readAuthenticationForRefreshToken(token.getValue());
- }
-
- public OAuth2Authentication readAuthenticationForRefreshToken(String token) {
- RedisConnection conn = getConnection();
- try {
- byte[] bytes = conn.get(serializeKey(REFRESH_AUTH + token));
- OAuth2Authentication auth = deserializeAuthentication(bytes);
- return auth;
- }
- finally {
- conn.close();
- }
- }
-
- @Override
- public void storeAccessToken(OAuth2AccessToken token, OAuth2Authentication authentication) {
- byte[] serializedAccessToken = serialize(token);
- byte[] serializedAuth = serialize(authentication);
- byte[] accessKey = serializeKey(ACCESS + token.getValue());
- byte[] authKey = serializeKey(AUTH + token.getValue());
- byte[] authToAccessKey = serializeKey(AUTH_TO_ACCESS + authenticationKeyGenerator.extractKey(authentication));
- byte[] approvalKey = serializeKey(UNAME_TO_ACCESS + getApprovalKey(authentication));
- byte[] clientId = serializeKey(CLIENT_ID_TO_ACCESS + authentication.getOAuth2Request().getClientId());
-
- RedisConnection conn = getConnection();
- try {
- conn.openPipeline();
- if (springDataRedis_2_0) {
- try {
- this.redisConnectionSet_2_0.invoke(conn, accessKey, serializedAccessToken);
- this.redisConnectionSet_2_0.invoke(conn, authKey, serializedAuth);
- this.redisConnectionSet_2_0.invoke(conn, authToAccessKey, serializedAccessToken);
- }
- catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
- else {
- conn.set(accessKey, serializedAccessToken);
- conn.set(authKey, serializedAuth);
- conn.set(authToAccessKey, serializedAccessToken);
- }
- if (!authentication.isClientOnly()) {
- conn.sAdd(approvalKey, serializedAccessToken);
- }
- conn.sAdd(clientId, serializedAccessToken);
- if (token.getExpiration() != null) {
- int seconds = token.getExpiresIn();
- conn.expire(accessKey, seconds);
- conn.expire(authKey, seconds);
- conn.expire(authToAccessKey, seconds);
- conn.expire(clientId, seconds);
- conn.expire(approvalKey, seconds);
- }
- OAuth2RefreshToken refreshToken = token.getRefreshToken();
- if (refreshToken != null && refreshToken.getValue() != null) {
- byte[] refresh = serialize(token.getRefreshToken().getValue());
- byte[] auth = serialize(token.getValue());
- byte[] refreshToAccessKey = serializeKey(REFRESH_TO_ACCESS + token.getRefreshToken().getValue());
- byte[] accessToRefreshKey = serializeKey(ACCESS_TO_REFRESH + token.getValue());
- if (springDataRedis_2_0) {
- try {
- this.redisConnectionSet_2_0.invoke(conn, refreshToAccessKey, auth);
- this.redisConnectionSet_2_0.invoke(conn, accessToRefreshKey, refresh);
- }
- catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
- else {
- conn.set(refreshToAccessKey, auth);
- conn.set(accessToRefreshKey, refresh);
- }
- if (refreshToken instanceof ExpiringOAuth2RefreshToken) {
- ExpiringOAuth2RefreshToken expiringRefreshToken = (ExpiringOAuth2RefreshToken) refreshToken;
- Date expiration = expiringRefreshToken.getExpiration();
- if (expiration != null) {
- int seconds = Long.valueOf((expiration.getTime() - System.currentTimeMillis()) / 1000L)
- .intValue();
- conn.expire(refreshToAccessKey, seconds);
- conn.expire(accessToRefreshKey, seconds);
- }
- }
- }
-
- // KEY
- byte[] key = serializeKey(String.format("%s%s", SecurityConstants.TOKEN_PREFIX, authentication.getName()));
- // value
- byte[] tokenVal = serialize(token.getValue());
- RedisStringCommands stringCommand = conn.stringCommands();
- stringCommand.set(key, tokenVal, Expiration.seconds(token.getExpiresIn()),
- RedisStringCommands.SetOption.SET_IF_ABSENT);
- conn.closePipeline();
- }
- finally {
- conn.close();
- }
- }
-
- @Override
- public void removeAccessToken(OAuth2AccessToken accessToken) {
- removeAccessToken(accessToken.getValue());
- }
-
- @Override
- public OAuth2AccessToken readAccessToken(String tokenValue) {
- byte[] key = serializeKey(ACCESS + tokenValue);
- byte[] bytes;
- RedisConnection conn = getConnection();
- try {
- bytes = conn.get(key);
- }
- finally {
- conn.close();
- }
- OAuth2AccessToken accessToken = deserializeAccessToken(bytes);
- return accessToken;
- }
-
- public void removeAccessToken(String tokenValue) {
- byte[] accessKey = serializeKey(ACCESS + tokenValue);
- byte[] authKey = serializeKey(AUTH + tokenValue);
- byte[] accessToRefreshKey = serializeKey(ACCESS_TO_REFRESH + tokenValue);
- RedisConnection conn = getConnection();
- try {
- conn.openPipeline();
- conn.get(accessKey);
- conn.get(authKey);
- conn.del(accessKey);
- conn.del(accessToRefreshKey);
- // Don't remove the refresh token - it's up to the caller to do that
- conn.del(authKey);
- List