From 3a1b824203d9e6a4c2a55e2d0d8adc0bae4f03d0 Mon Sep 17 00:00:00 2001
From: zf <1603559716@qq.com>
Date: 星期一, 25 三月 2024 13:11:32 +0800
Subject: [PATCH] 安全物资和设备管理调整v2

---
 safePlatfrom-out-web/src/main/java/com/gkhy/safePlatform/config/security/TokenAuthenticationFilter.java |  128 ++++++++++++++++++------------------------
 1 files changed, 55 insertions(+), 73 deletions(-)

diff --git a/safePlatfrom-out-web/src/main/java/com/gkhy/safePlatform/config/security/TokenAuthenticationFilter.java b/safePlatfrom-out-web/src/main/java/com/gkhy/safePlatform/config/security/TokenAuthenticationFilter.java
index 1316c2a..9a880a9 100644
--- a/safePlatfrom-out-web/src/main/java/com/gkhy/safePlatform/config/security/TokenAuthenticationFilter.java
+++ b/safePlatfrom-out-web/src/main/java/com/gkhy/safePlatform/config/security/TokenAuthenticationFilter.java
@@ -10,6 +10,7 @@
 import com.gkhy.safePlatform.commons.enums.ResultCodes;
 import com.gkhy.safePlatform.commons.exception.BusinessException;
 import com.gkhy.safePlatform.commons.utils.RPCUtils;
+import com.gkhy.safePlatform.commons.utils.RequestContextHolder;
 import com.gkhy.safePlatform.commons.utils.StringUtils;
 import com.gkhy.safePlatform.commons.vo.ResultVO;
 import com.gkhy.safePlatform.config.redis.RedisUtils;
@@ -29,6 +30,7 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 
 /**
@@ -68,97 +70,77 @@
     private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest req,HttpServletResponse resp) {
         // header获取token
         String authToken = req.getHeader(tokenConfig.getHeader());
-        String loginUserId = req.getHeader(tokenConfig.getLoginUserHeader());
-
         if(authToken != null) {
-            // header 传入 userId
-            if (StringUtils.isBlank(loginUserId)) {
-                throw new BusinessException(ResultCodes.CLIENT_CREDENTIALS_LACK);
-            }
             // 登录成功时,会将权限数据存入redis
             // 这里是验证获取权限信息
             // 1.从redis中获取对应该用户的权限信息
-            String accessTokenKey = RedisKeyEnum.authKey(RedisKeyEnum.AUTH_TOKEN, loginUserId);
+            String accessTokenKey = RedisKeyEnum.authKey(RedisKeyEnum.AUTH_TOKEN, authToken);
             Object o = redisUtils.get(accessTokenKey);
             // 2.token是否存在
             if (o == null) {
-                // 是否存在
+                // 是否存在 uid未登录
                 throw new BusinessException(ResultCodes.CLIENT_CREDENTIALS_TOKEN_INVALID);
             }else{
-                Long userId = Long.valueOf(loginUserId);
-                ContextCacheUser contextCacheUser = JSONObject.parseObject(o.toString(), ContextCacheUser.class);
-                assert userId.equals(contextCacheUser.getUid());
-                if ( !authToken.equals(contextCacheUser.getAccessToken())) {
-                    throw new BusinessException(ResultCodes.CLIENT_CREDENTIALS_TOKEN_INVALID);
+                // todo 可以不转换,建议rpc传入string
+                String uid = o.toString();
+                Long userId = Long.valueOf(uid);
+                String accessUserKey = RedisKeyEnum.authKey(RedisKeyEnum.AUTH_USER, userId);
+                // 这里不做用户信息的token判断 放入登录
+                Long expireSecondsLeft = redisUtils.getExpireTime(accessTokenKey);
+                // 60m 内请求则续期 时长为原本的有效时间
+                if (expireSecondsLeft != null && 0L < expireSecondsLeft && expireSecondsLeft < 60 * 60) {
+                    // 重置token:uid
+                    redisUtils.resetKeyExpireTime(accessTokenKey, tokenConfig.getExpiration());
+                    // 重置uid:userInfo
+                    redisUtils.resetKeyExpireTime(accessUserKey, tokenConfig.getExpiration());
                 }
-
-                // 3.redis获取权限
-                String authoritiesKey = RedisKeyEnum.authKey(RedisKeyEnum.AUTH_AUTHORITIES, userId);
-                Object oo = redisUtils.get(authoritiesKey);
-                List<GrantedAuthority> authorities = new ArrayList<>();
-                // 4.redis中是否存在
-                if (oo != null) {
-                    // 5.存在
-                    List<ContextCacheAuthority> cacheAuthorities = JSONArray.parseArray(oo.toString(), ContextCacheAuthority.class);
-                    for (ContextCacheAuthority cacheAuthority: cacheAuthorities) {
-                        authorities.add(new SimpleGrantedAuthority(cacheAuthority.getAuthority()));
-                    }
-                }else {
-                    // 6.不存在=>数据库查询
-                    ResultVO<String> rpcResultRole = userAccountService.getUserRoleCodeByUserId(userId);
-
-                    if (rpcResultRole == null) {
-                        throw new BusinessException(ResultCodes.RPC_RESULT_NULL);
-                    }
-                    if (!ResultCodes.OK.getCode().equals(rpcResultRole.getCode())) {
-                        throw new BusinessException(rpcResultRole.getCode(), rpcResultRole.getMsg());
-                    }
-                    if (rpcResultRole.getData() == null) {
-                        throw new BusinessException(ResultCodes.RPC_DATA_NULL);
-                    }
-                    if (!(rpcResultRole.getData() instanceof String)) {
-                        throw new BusinessException(ResultCodes.RPC_DATA_TYPE_NOT_MATCH);
-                    }
-                    // role
-                    authorities.add(new SimpleGrantedAuthority("ROLE_" + rpcResultRole.getData().toString()));
-
-                    // permission
-                    ResultVO<List<String>> rpcResultPermission = userAccountService.getUserPermissionByUserId(userId);
-
-                    if (rpcResultPermission == null) {
-                        throw new BusinessException(ResultCodes.RPC_RESULT_NULL);
-                    }
-                    if (!ResultCodes.OK.getCode().equals(rpcResultPermission.getCode())) {
-                        throw new BusinessException(rpcResultRole.getCode(), rpcResultRole.getMsg());
-                    }
-                    if (rpcResultPermission.getData() == null) {
-                        throw new BusinessException(ResultCodes.RPC_DATA_NULL);
-                    }
-                    if (!(rpcResultPermission.getData() instanceof List)) {
-                        throw new BusinessException(ResultCodes.RPC_DATA_TYPE_NOT_MATCH);
-                    }
-
-                    List<String> permissions = RPCUtils.castList(rpcResultPermission.getData(), String.class);
-                    for (String permission : permissions) {
-                        SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(permission);
-                        authorities.add(simpleGrantedAuthority);
-                    }
+                // 获取用户信息
+                Object oo = redisUtils.get(accessUserKey);
+                // 初始化
+                ContextCacheUser contextCacheUser = null;
+                if (oo == null) {
+                    // 业务逻辑上是不会空的
+                    // 实际操作可能会手动清空
+                    ResultVO<ContextCacheUser> rpcResultVo = userAccountService.getCacheUserDetailByUid(userId);
+                    // 调用rpc返回的数据 没有token 所以得至少续上这次token
+                    contextCacheUser = this.getRpcResult(rpcResultVo);
+                    // 因为手动清空等原因,可能会丢失其他token数据,就不去一一搜索这个uid的token了
+                    contextCacheUser.setAccessToken(Collections.singletonList(authToken));
+                }else{
+                    // 正常的实际场景必定会走这里
+                    // 推荐用jackson
+                    contextCacheUser = JSONObject.parseObject(oo.toString(), ContextCacheUser.class);
                 }
-
+                // threadLocal存入用户信息
+                RequestContextHolder.contextUserLocal.set(contextCacheUser);
                 // security对象中存入登陆者信息
-                return new UsernamePasswordAuthenticationToken(contextCacheUser,authToken,authorities);
+                return new UsernamePasswordAuthenticationToken(contextCacheUser, authToken, contextCacheUser.getAuthorities());
 
             }
-
-
-
-
-
-
         }
         return null;
     }
 
+    /**
+     * 获取rpc 返回的用户数据
+     *
+     * @param rpcResultVo rpc返回数据
+     * @return 用户准备缓存的数据
+     */
+    private ContextCacheUser getRpcResult(ResultVO<ContextCacheUser> rpcResultVo) {
+        if (!rpcResultVo.getCode().equals(ResultCodes.OK.getCode())) {
+            throw new BusinessException(rpcResultVo.getCode(), rpcResultVo.getMsg());
+        }
+        if (rpcResultVo.getData() == null) {
+            throw new BusinessException(ResultCodes.RPC_DATA_NULL);
+        }
+        if (rpcResultVo.getData() instanceof ContextCacheUser) {
+            return (ContextCacheUser) rpcResultVo.getData();
+        } else {
+            throw new BusinessException(ResultCodes.RPC_DATA_TYPE_NOT_MATCH);
+        }
+
+    }
 
 
     protected void writeJSON(HttpServletRequest req,

--
Gitblit v1.9.2