Browse Source

修复febs-auth在集群时的一些问题

MrBird 5 years ago
parent
commit
4b0679a6cd

+ 8 - 0
febs-auth/pom.xml

@@ -66,6 +66,14 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-thymeleaf</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.springframework.session</groupId>
+            <artifactId>spring-session-core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.springframework.session</groupId>
+            <artifactId>spring-session-data-redis</artifactId>
+        </dependency>
     </dependencies>
 
     <build>

+ 2 - 0
febs-auth/src/main/java/cc/mrbird/febs/auth/FebsAuthApplication.java

@@ -5,11 +5,13 @@ import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.WebApplicationType;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.builder.SpringApplicationBuilder;
+import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
 
 /**
  * @author MrBird
  */
 @SpringBootApplication
+@EnableRedisHttpSession
 @EnableFebsCloudResourceServer
 @MapperScan("cc.mrbird.febs.auth.mapper")
 public class FebsAuthApplication {

+ 3 - 0
febs-auth/src/main/java/cc/mrbird/febs/auth/configure/FebsAuthorizationServerConfigure.java

@@ -1,6 +1,7 @@
 package cc.mrbird.febs.auth.configure;
 
 import cc.mrbird.febs.auth.properties.FebsAuthProperties;
+import cc.mrbird.febs.auth.service.impl.RedisAuthenticationCodeService;
 import cc.mrbird.febs.auth.service.impl.RedisClientDetailsService;
 import cc.mrbird.febs.auth.translator.FebsWebResponseExceptionTranslator;
 import lombok.RequiredArgsConstructor;
@@ -43,6 +44,7 @@ public class FebsAuthorizationServerConfigure extends AuthorizationServerConfigu
     private final PasswordEncoder passwordEncoder;
     private final FebsWebResponseExceptionTranslator exceptionTranslator;
     private final FebsAuthProperties properties;
+    private final RedisAuthenticationCodeService authenticationCodeService;
     private final RedisClientDetailsService redisClientDetailsService;
     private final RedisConnectionFactory redisConnectionFactory;
 
@@ -56,6 +58,7 @@ public class FebsAuthorizationServerConfigure extends AuthorizationServerConfigu
     public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
         endpoints.tokenStore(tokenStore())
                 .userDetailsService(userDetailService)
+                .authorizationCodeServices(authenticationCodeService)
                 .authenticationManager(authenticationManager)
                 .exceptionTranslator(exceptionTranslator);
         if (properties.getEnableJwt()) {

+ 71 - 0
febs-auth/src/main/java/cc/mrbird/febs/auth/service/impl/RedisAuthenticationCodeService.java

@@ -0,0 +1,71 @@
+package cc.mrbird.febs.auth.service.impl;
+
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.ArrayUtils;
+import org.apache.commons.lang3.SerializationUtils;
+import org.springframework.data.redis.connection.RedisConnection;
+import org.springframework.data.redis.connection.RedisConnectionFactory;
+import org.springframework.security.oauth2.provider.OAuth2Authentication;
+import org.springframework.security.oauth2.provider.code.RandomValueAuthorizationCodeServices;
+import org.springframework.stereotype.Service;
+import org.springframework.util.Assert;
+
+import java.nio.charset.StandardCharsets;
+
+/**
+ * 授权码保存到Redis,以确保认证服务器集群的一致性
+ *
+ * @author MrBird
+ */
+@Slf4j
+@Service
+public class RedisAuthenticationCodeService extends RandomValueAuthorizationCodeServices {
+
+
+    private static final String AUTH_CODE_KEY = "auth_code";
+    private final RedisConnectionFactory connectionFactory;
+
+    public RedisAuthenticationCodeService(RedisConnectionFactory connectionFactory) {
+        Assert.notNull(connectionFactory, "RedisConnectionFactory required");
+        this.connectionFactory = connectionFactory;
+    }
+
+    @Override
+    protected OAuth2Authentication remove(String code) {
+        RedisConnection conn = getConnection();
+        try {
+            byte[] bytes = conn.hGet(AUTH_CODE_KEY.getBytes(StandardCharsets.UTF_8), code.getBytes(StandardCharsets.UTF_8));
+            if (bytes == null || ArrayUtils.isEmpty(bytes)) {
+                return null;
+            }
+            OAuth2Authentication authentication = SerializationUtils.deserialize(bytes);
+            if (null != authentication) {
+                conn.hDel(AUTH_CODE_KEY.getBytes(StandardCharsets.UTF_8), code.getBytes(StandardCharsets.UTF_8));
+            }
+            return authentication;
+        } catch (Exception e) {
+            return null;
+        } finally {
+            conn.close();
+        }
+    }
+
+    @Override
+    protected void store(String code, OAuth2Authentication authentication) {
+        RedisConnection conn = getConnection();
+        try {
+            conn.hSet(AUTH_CODE_KEY.getBytes(StandardCharsets.UTF_8), code.getBytes(StandardCharsets.UTF_8),
+                    SerializationUtils.serialize(authentication));
+            log.info("保存authentication code: {}至redis", code);
+        } catch (Exception e) {
+            log.error("保存authentication code至redis失败", e);
+        } finally {
+            conn.close();
+        }
+    }
+
+    private RedisConnection getConnection() {
+        return connectionFactory.getConnection();
+    }
+
+}