From d015cc0b48ca51a2b93b6c60c91dc352a104b1e7 Mon Sep 17 00:00:00 2001 From: kongzy <kongzy> Date: 星期一, 23 九月 2024 10:41:50 +0800 Subject: [PATCH] 删除密码加密 --- safePlatfrom-out-web/src/main/java/com/gkhy/safePlatform/config/security/TokenAuthenticationFilter.java | 316 ++++++++++++++++++++++++++------------------------- 1 files changed, 161 insertions(+), 155 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 c9bd858..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 @@ -1,155 +1,161 @@ -//package com.gkhy.safePlatform.config.security; -// -//import com.alibaba.fastjson.JSONArray; -//import com.alibaba.fastjson.JSONObject; -//import com.gkhy.safePlatform.account.model.cache.CacheUser; -//import com.gkhy.safePlatform.account.rpc.apimodel.NameService; -//import com.gkhy.safePlatform.commons.config.token.TokenConfig; -//import com.gkhy.safePlatform.commons.enums.RedisKeyEnum; -//import com.gkhy.safePlatform.commons.enums.ResultCodes; -//import com.gkhy.safePlatform.commons.exception.BusinessException; -//import com.gkhy.safePlatform.commons.utils.RedisUtils; -//import com.gkhy.safePlatform.commons.utils.StringUtils; -//import com.gkhy.safePlatform.commons.vo.ResultVO; -//import org.apache.dubbo.config.annotation.DubboReference; -//import org.springframework.beans.factory.annotation.Autowired; -//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -//import org.springframework.security.core.GrantedAuthority; -//import org.springframework.security.core.authority.SimpleGrantedAuthority; -//import org.springframework.security.core.context.SecurityContextHolder; -//import org.springframework.stereotype.Component; -//import org.springframework.web.filter.OncePerRequestFilter; -// -//import javax.servlet.FilterChain; -//import javax.servlet.ServletException; -//import javax.servlet.http.HttpServletRequest; -//import javax.servlet.http.HttpServletResponse; -//import java.io.IOException; -//import java.io.PrintWriter; -//import java.util.ArrayList; -//import java.util.List; -// -///** -//* @Description: token登录过滤器 -//*/ -//@Component -//public class TokenAuthenticationFilter extends OncePerRequestFilter { -// -// @Autowired -// private TokenConfig tokenConfig; -// @Autowired -// private RedisUtils redisUtil; -// @DubboReference(check = false) -// private NameService nameService; -// -// -// -// @Override -// protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws IOException, ServletException { -// -// try { -// //获取当前认证成功用户权限信息 -// UsernamePasswordAuthenticationToken authRequest = getAuthentication(req, resp); -// if (authRequest != null) { -// SecurityContextHolder.getContext().setAuthentication(authRequest); -// } -// // 执行下一个 filter 过滤器链 -// chain.doFilter(req, resp); -// } catch (BusinessException e) { -// // 返回异常 -// this.writeJSON(req, resp, new ResultVO<>(e.getError())); -// } catch (Exception e) { -// e.printStackTrace(); -// this.writeJSON(req, resp, new ResultVO<>(ResultCodes.SERVER_ERROR)); -// } -// -// -// } -// -// -// 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); -// Object o = redisUtil.get(accessTokenKey); -// // 2.token是否存在 -// if (o == null) { -// // 是否存在 -// throw new BusinessException(ResultCodes.CLIENT_CREDENTIALS_SIGN_INVALID); -// }else{ -// Long userId = Long.valueOf(loginUserId); -// CacheUser cacheUser = JSONObject.parseObject(o.toString(), CacheUser.class); -// assert userId.equals(cacheUser.getUserId()); -// if ( !authToken.equals(cacheUser.getAccessToken())) { -// throw new BusinessException(ResultCodes.CLIENT_CREDENTIALS_TOKEN_INVALID); -// } -// -// // 3.redis获取权限 -// String authoritiesKey = RedisKeyEnum.authKey(RedisKeyEnum.AUTH_AUTHORITIES, userId); -// Object oo = redisUtil.get(authoritiesKey); -// List<GrantedAuthority> authorities; -// // 4.redis中是否存在 -// if (oo != null) { -// // 5.存在 -// String json = oo.toString(); -// authorities = JSONArray.parseArray(json, GrantedAuthority.class); -// }else { -// authorities = new ArrayList<>(); -// // 6.不存在=>数据库查询 -// List<String> roleCodes = nameService.getUserRoleCodeByUserId(userId); -// // role -// for (String roleCode : roleCodes) { -// SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority("ROLE_" + roleCode); -// authorities.add(simpleGrantedAuthority); -// } -// -// // permission -// List<String> permissions = nameService.getUserPermissionByUserId(userId); -// for (String permission : permissions) { -// SimpleGrantedAuthority simpleGrantedAuthority = new SimpleGrantedAuthority(permission); -// authorities.add(simpleGrantedAuthority); -// } -// } -// -// // security对象中存入登陆者信息 -// return new UsernamePasswordAuthenticationToken(userId,authToken,authorities); -// -// } -// -// -// -// -// -// -// } -// return null; -// } -// -// -// -// protected void writeJSON(HttpServletRequest req, -// HttpServletResponse resp, -// ResultVO resultVO) throws IOException { -// // 设置编码格式 -// resp.setContentType("text/json;charset=utf-8"); -// // 处理跨域问题 -// resp.setHeader("Access-Control-Allow-Origin", "*"); -// resp.setHeader("Access-Control-Allow-Methods", "POST, GET"); -// -// //输出JSON -// PrintWriter out = resp.getWriter(); -// out.write(JSONObject.toJSONString(resultVO)); -// out.flush(); -// out.close(); -// } -//} +package com.gkhy.safePlatform.config.security; + +import com.alibaba.fastjson.JSONArray; +import com.alibaba.fastjson.JSONObject; +import com.gkhy.safePlatform.account.rpc.apimodel.AccountAuthService; +import com.gkhy.safePlatform.account.rpc.apimodel.AccountAuthService; +import com.gkhy.safePlatform.commons.co.ContextCacheAuthority; +import com.gkhy.safePlatform.commons.co.ContextCacheUser; +import com.gkhy.safePlatform.commons.enums.RedisKeyEnum; +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; +import org.apache.dubbo.config.annotation.DubboReference; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** +* @Description: token登录过滤器 +*/ +@Component +public class TokenAuthenticationFilter extends OncePerRequestFilter { + + @Autowired + private TokenConfig tokenConfig; + @DubboReference(check = false) + private AccountAuthService userAccountService; + @Autowired + private RedisUtils redisUtils; + + + + @Override + protected void doFilterInternal(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws IOException, ServletException { + + try { + //获取当前认证成功用户权限信息 + UsernamePasswordAuthenticationToken authRequest = getAuthentication(req, resp); + if (authRequest != null) { + SecurityContextHolder.getContext().setAuthentication(authRequest); + } + // 执行下一个 filter 过滤器链 + chain.doFilter(req, resp); + } catch (BusinessException e) { + // 返回异常 + this.writeJSON(req, resp, new ResultVO<>(e.getCode(),e.getMessage())); + } + + } + + + private UsernamePasswordAuthenticationToken getAuthentication(HttpServletRequest req,HttpServletResponse resp) { + // header获取token + String authToken = req.getHeader(tokenConfig.getHeader()); + if(authToken != null) { + // 登录成功时,会将权限数据存入redis + // 这里是验证获取权限信息 + // 1.从redis中获取对应该用户的权限信息 + 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{ + // 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()); + } + // 获取用户信息 + 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, 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, + HttpServletResponse resp, + ResultVO resultVO) throws IOException { + // 设置编码格式 + resp.setContentType("text/json;charset=utf-8"); + // 处理跨域问题 + resp.setHeader("Access-Control-Allow-Origin", "*"); + resp.setHeader("Access-Control-Allow-Methods", "POST, GET"); + + //输出JSON + PrintWriter out = resp.getWriter(); + out.write(JSONObject.toJSONString(resultVO)); + out.flush(); + out.close(); + } +} -- Gitblit v1.9.2