Browse Source

代码优化

woody 11 months ago
parent
commit
4eebc12fb8

+ 2 - 2
framework-base/src/main/java/com/chelvc/framework/base/context/RestContextHolder.java

@@ -1,5 +1,6 @@
 package com.chelvc.framework.base.context;
 
+import java.io.IOException;
 import java.net.URI;
 import java.util.Arrays;
 import java.util.Map;
@@ -9,7 +10,6 @@ import com.chelvc.framework.common.util.ErrorUtils;
 import com.chelvc.framework.common.util.ObjectUtils;
 import lombok.NonNull;
 import lombok.extern.slf4j.Slf4j;
-import org.apache.http.NoHttpResponseException;
 import org.springframework.core.ParameterizedTypeReference;
 import org.springframework.http.HttpEntity;
 import org.springframework.http.HttpMethod;
@@ -59,7 +59,7 @@ public final class RestContextHolder {
         try {
             return function.apply(getTemplate());
         } catch (Exception e) {
-            if (ErrorUtils.contains(e, NoHttpResponseException.class)) {
+            if (ErrorUtils.contains(e, IOException.class)) {
                 log.warn("Rest invoke failed and retry later: {}", e.getMessage());
                 // 请求重试
                 return function.apply(new RestTemplate());

+ 51 - 5
framework-oauth/src/main/java/com/chelvc/framework/oauth/token/DefaultSessionValidator.java

@@ -1,7 +1,14 @@
 package com.chelvc.framework.oauth.token;
 
+import java.util.Set;
+
+import com.chelvc.framework.base.context.ApplicationContextHolder;
 import com.chelvc.framework.base.context.SessionContextHolder;
+import com.chelvc.framework.common.util.StringUtils;
 import com.chelvc.framework.oauth.context.OAuthContextHolder;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
+import org.springframework.security.oauth2.core.OAuth2Error;
 import org.springframework.security.oauth2.core.OAuth2TokenValidatorResult;
 import org.springframework.security.oauth2.jwt.Jwt;
 
@@ -11,15 +18,54 @@ import org.springframework.security.oauth2.jwt.Jwt;
  * @author Woody
  * @date 2024/6/29
  */
+@Slf4j
 public class DefaultSessionValidator implements SessionValidator {
+    /**
+     * 获取主体身份
+     *
+     * @param jwt JWT对象
+     * @return 主体身份标识
+     */
+    protected Long getId(Jwt jwt) {
+        try {
+            return OAuthContextHolder.getId(jwt);
+        } catch (Exception e) {
+            log.error("JWT id convert failed", e);
+            throw new OAuth2AuthenticationException(new OAuth2Error(
+                    "TOKEN_EXPIRED", ApplicationContextHolder.getMessage("Token.Expired"), null
+            ));
+        }
+    }
+
+    /**
+     * 获取应用范围
+     *
+     * @param jwt Jwt对象
+     * @return 应用范围
+     */
+    protected String getScope(Jwt jwt) {
+        String scope = OAuthContextHolder.getScope(jwt);
+        if (StringUtils.isEmpty(scope)) {
+            // 兼容框架1.0版本
+            return StringUtils.ifEmpty(jwt.getClaimAsString("type"), (String) null);
+        }
+        return scope;
+    }
+
+    /**
+     * 获取用户授权信息
+     *
+     * @param jwt JWT对象
+     * @return 授权信息集合
+     */
+    protected Set<String> getAuthorities(Jwt jwt) {
+        return OAuthContextHolder.getAuthorities(jwt);
+    }
+
     @Override
     public OAuth2TokenValidatorResult validate(Jwt jwt) {
         if (!OAuthContextHolder.isClient(jwt)) {
-            SessionContextHolder.setSession(
-                    OAuthContextHolder.getId(jwt),
-                    OAuthContextHolder.getScope(jwt),
-                    OAuthContextHolder.getAuthorities(jwt)
-            );
+            SessionContextHolder.setSession(this.getId(jwt), this.getScope(jwt), this.getAuthorities(jwt));
         }
         return OAuth2TokenValidatorResult.success();
     }

+ 9 - 4
framework-oauth/src/main/java/com/chelvc/framework/oauth/token/RedisSessionValidator.java

@@ -15,6 +15,7 @@ import com.chelvc.framework.redis.context.RedisContextHolder;
 import com.chelvc.framework.redis.context.RedisHashHolder;
 import com.chelvc.framework.redis.context.RedisUserDailyHashHolder;
 import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
@@ -31,11 +32,12 @@ import org.springframework.stereotype.Component;
  * @author Woody
  * @date 2024/1/30
  */
+@Slf4j
 @Component
 @ConditionalOnClass(RedisContextHolder.class)
 @ConditionalOnProperty(value = "oauth.redis.enabled", havingValue = "true", matchIfMissing = true)
 @RequiredArgsConstructor(onConstructor = @__(@Autowired))
-public class RedisSessionValidator implements SessionValidator {
+public class RedisSessionValidator extends DefaultSessionValidator {
     private final OAuthProperties properties;
 
     @Override
@@ -45,7 +47,7 @@ public class RedisSessionValidator implements SessionValidator {
         }
 
         // 从Redis获取令牌信息
-        Long id = OAuthContextHolder.getId(jwt);
+        Long id = this.getId(jwt);
         String terminal = String.valueOf(SessionContextHolder.getTerminal());
         RedisTemplate<String, Object> template = RedisContextHolder.getDefaultTemplate();
         List<?> values = RedisHashHolder.get(
@@ -54,8 +56,11 @@ public class RedisSessionValidator implements SessionValidator {
         );
 
         // 校验令牌有效性及应用范围
-        String token = ObjectUtils.get(values, 0);
-        String scope = OAuthContextHolder.getScope(jwt);
+        String token = ObjectUtils.get(values, 0), scope = this.getScope(jwt);
+        if (StringUtils.isEmpty(token)) {
+            // 兼容框架1.0版本
+            token = (String) template.opsForValue().get("token:" + terminal + ":" + id);
+        }
         if (StringUtils.isEmpty(token)) {
             throw new OAuth2AuthenticationException(new OAuth2Error(
                     "TOKEN_EXPIRED", ApplicationContextHolder.getMessage("Token.Expired"), null