import cn.hutool.core.net.URLEncodeUtil;import cn.hutool.core.util.StrUtil;import com.alibaba.fastjson.JSON;import com.evun.platform.common.Result;import com.geely.usms.config.props.GeelySsoProp;import com.geely.usms.config.props.LoginWhitesProp;import com.geely.usms.config.props.TokenColumnProp;import com.geely.usms.enums.ExceptionEnums;import com.geely.usms.user.SessionUserInt;import com.geely.usms.user.SessionUserUtil;import com.geely.usms.util.CookieUtil;import com.geely.usms.util.RedisTemplateUtil;import com.geely.usms.util.UserContextUtil;import com.geely.usms.vo.login.GeelyLoginUserVO;import lombok.EqualsAndHashCode;import lombok.RequiredArgsConstructor;import lombok.extern.slf4j.Slf4j;import org.apache.commons.lang3.StringUtils;import org.springframework.core.env.Environment;import org.springframework.core.env.Profiles;import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;import org.springframework.security.core.authority.SimpleGrantedAuthority;import org.springframework.security.core.context.SecurityContextHolder;import org.springframework.util.AntPathMatcher;import org.springframework.util.PathMatcher;import javax.servlet.*;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.Collections;import java.util.List;import java.util.Optional;import java.util.stream.Collectors;/** * @author :duanyi * @date :Created 2022/10/12 15:46 * @description: 过滤验证类 */@EqualsAndHashCode@Slf4j@RequiredArgsConstructorpublic class CustomSsoFilter implements Filter { private static final PathMatcher pathMatcher = new AntPathMatcher(); private final GeelySsoProp geelySsoProp; private final LoginWhitesProp loginWhitesProp; private final TokenColumnProp tokenColumnProp; private final Environment standardServletEnvironment; private final RedisTemplateUtil redisTemplateUtil; @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { // 开发环境直接放行 HttpServletRequest req = (HttpServletRequest) servletRequest; HttpServletResponse resp = (HttpServletResponse) servletResponse; resp.setHeader("Access-Control-Allow-Origin", "http://localhost:5174"); resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE, PUT"); resp.setHeader("Access-Control-Max-Age", "3600"); resp.setHeader("Access-Control-Allow-Headers", "*"); resp.setHeader("Access-Control-Allow-Credentials", "true"); if ("OPTIONS".equalsIgnoreCase(req.getMethod())) { resp.setStatus(HttpServletResponse.SC_OK); } if (isIgnoreUrls(req)) { //设置spring security handleSpringSecurity(SessionUserInt.getSystemUser()); // 如果是免登录的,放行给后面处理 filterChain.doFilter(req, resp); return; } // 如果不是免登录的,走sso的相关校验 // 获取请求头中的令牌(token) String token = getToken(req); if (StrUtil.isEmpty(token) && pathMatcher.match("/doc.html", req.getServletPath())) { String currentUrl = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + req.getRequestURI() + (req.getQueryString() != null ? "?" + req.getQueryString() : ""); log.info("redirectUrl:{}", currentUrl); String encodedUrl = URLEncodeUtil.encodeAll(currentUrl); resp.sendRedirect("/api/admin/login/sso?redirectUrl=" + encodedUrl); return; } if (StringUtils.isEmpty(token)) { errorHandle(resp, HttpServletResponse.SC_UNAUTHORIZED, ExceptionEnums.AUTH_NO_TOKEN.getMessage()); return; } Optional<GeelyLoginUserVO> loginUserVO = getSessionUser(token); if (!loginUserVO.isPresent()) { errorHandle(resp, HttpServletResponse.SC_UNAUTHORIZED, ExceptionEnums.USER_LOGIN_OVERDUE.getMessage()); return; } try { UserContextUtil.setUser(loginUserVO.get()); // 设置spring security handleSpringSecurity(loginUserVO.get()); filterChain.doFilter(req, resp); } finally { UserContextUtil.clear(); SessionUserUtil.clear(); } } /** * Description: 添加Spring Security认证信息 * @author Jie.Zhang41 * @param sessionUserInt sessionUserInt */ private void handleSpringSecurity(SessionUserInt sessionUserInt) { // 设置用户session 信息 SessionUserUtil.setUserSupplier(sessionUserInt); // 获取用户权限 List<SimpleGrantedAuthority> userAuthorities = Optional.ofNullable(sessionUserInt) .map(SessionUserInt::getPermCodes) .orElse(Collections.emptyList()) .stream() .map(SimpleGrantedAuthority::new) .collect(Collectors.toList()); // Spring Security 认证信息设置 UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(sessionUserInt.getId(), null, userAuthorities); SecurityContextHolder.getContext().setAuthentication(authentication); } /** * 判断是否是免登录的 * * @param httpServletRequest * @return */ private boolean isIgnoreUrls(HttpServletRequest httpServletRequest) { String requestUrl = httpServletRequest.getServletPath(); if (StringUtils.isEmpty(requestUrl)) { return false; } return loginWhitesProp.getUrls().stream() .filter(StringUtils::isNotBlank) .anyMatch(ignoreUrl -> pathMatcher.match(ignoreUrl.trim(), requestUrl)); } /** * 判断是否是开发环境 * * @return */ public boolean isDev() { if (standardServletEnvironment == null) { return false; } Profiles profiles = Profiles.of("local"); return standardServletEnvironment.acceptsProfiles(profiles); } private void errorHandle(HttpServletResponse resp, int statusCode, String msg) throws IOException { resp.setStatus(statusCode); resp.setContentType("application/json"); resp.getWriter().write(JSON.toJSONString(// Result.error(msg) Result.of(statusCode, msg, "",geelySsoProp.getPassportUrl() + "?appKey=" + geelySsoProp.getAppKey() + "&resourceType=4") )); } /** * Description: 获取token, 有限从请求头获取,再从cookie获取 * @author Jie.Zhang41 * @date 2025/4/28 */ private String getToken(HttpServletRequest request) { String tokenStr = getTokenFromHeader(request); if (StrUtil.isNotBlank(tokenStr)) { return tokenStr; } return getTokenFromCookie(request); } /** * Description: 从请求头获取 token * @author Jie.Zhang41 * @date 2025/4/28 */ private String getTokenFromHeader(HttpServletRequest request) { String token = request.getHeader(tokenColumnProp.getHeader()); if (StringUtils.isNotEmpty(token) && token.startsWith(TokenColumnProp.TOKEN_PREFIX)) { token = token.replace(TokenColumnProp.TOKEN_PREFIX, ""); } return token; } /** * Description: 从Cookie获取 token * @author Jie.Zhang41 * @date 2025/4/28 */ private String getTokenFromCookie(HttpServletRequest request) { return CookieUtil.getCookieValue(request, tokenColumnProp.getCookie()); } /** * Description: redis 中获取用户 * @author Jie.Zhang41 * @date 2025/4/29 * @param token token * @return com.geely.usms.vo.login.GeelyLoginUserVO */ private Optional<GeelyLoginUserVO> getSessionUser(String token) { String userInfoStr = redisTemplateUtil.get(SessionUserUtil.getSessionUserRedKey(token)); return Optional.ofNullable(userInfoStr) .map(json -> JSON.parseObject(json, GeelyLoginUserVO.class)); }} 过滤器 设置
2025-09-25
本文作者: linden
原文链接: 过滤器 设置
版权声明: 本站所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
免责声明: 文中如涉及第三方资源,均来自互联网,仅供学习研究,禁止商业使用,如有侵权,联系我们24小时内删除!
- « 上一篇cookie 工具类
- 下一篇 »没有了
评论0
暂时没有评论