From 29f5825e22f8ed6cc2019511ad75a4939bafb6a8 Mon Sep 17 00:00:00 2001
From: lyfO_o <764716047@qq.com>
Date: 星期六, 06 五月 2023 16:00:35 +0800
Subject: [PATCH] 用户token 过滤链判断限制
---
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