package com.yami.trading.security.common.filter; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.StrUtil; import com.yami.trading.security.common.adapter.AuthConfigAdapter; import com.yami.trading.security.common.manager.TokenStore; import com.yami.trading.common.exception.YamiShopBindException; import com.yami.trading.common.handler.HttpHandler; import com.yami.trading.security.common.bo.UserInfoInTokenBO; import com.yami.trading.security.common.util.AuthUserContext; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.util.AntPathMatcher; import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.List; /** * 授权过滤,只要实现AuthConfigAdapter接口,添加对应路径即可: * * @author 菠萝凤梨 * @date 2022/3/25 17:33 */ @Component public class AuthFilter implements Filter { @Autowired private AuthConfigAdapter authConfigAdapter; @Autowired private HttpHandler httpHandler; @Autowired private TokenStore tokenStore; @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse resp = (HttpServletResponse) response; String requestUri = req.getRequestURI(); List excludePathPatterns = authConfigAdapter.excludePathPatterns(); AntPathMatcher pathMatcher = new AntPathMatcher(); // 如果匹配不需要授权的路径,就不需要校验是否需要授权 if (CollectionUtil.isNotEmpty(excludePathPatterns)) { for (String excludePathPattern : excludePathPatterns) { if (pathMatcher.match(excludePathPattern, requestUri)) { chain.doFilter(req, resp); return; } } } String token = req.getHeader("token"); String accessToken = req.getHeader("Authorization"); if (StrUtil.isEmpty(accessToken)) { accessToken = token; } if (StrUtil.isEmpty(accessToken)) { accessToken = req.getParameter("token"); } // 也许需要登录,不登陆也能用的uri List maybeAuthUris = authConfigAdapter.maybeAuthUri(); boolean mayAuth = false; if (CollectionUtil.isNotEmpty(maybeAuthUris)) { for (String maybe : maybeAuthUris) { if (pathMatcher.match(maybe, requestUri)) { mayAuth = true; break; } } } UserInfoInTokenBO userInfoInToken = null; try { // 如果有token,就要获取token if (StrUtil.isNotBlank(accessToken)) { userInfoInToken = tokenStore.getUserInfoByAccessToken(accessToken, true); } else if (!mayAuth) { // 返回前端401 httpHandler.printServerResponseToWeb(HttpStatus.UNAUTHORIZED.getReasonPhrase(), HttpStatus.UNAUTHORIZED.value()); return; } // 保存上下文 AuthUserContext.set(userInfoInToken); chain.doFilter(req, resp); } catch (Exception e) { // 手动捕获下非controller异常 if (e instanceof YamiShopBindException) { httpHandler.printServerResponseToWeb(e.getMessage(), 200); } else { throw e; } } finally { AuthUserContext.clean(); } } }