package com.jilongda.applet.config; import com.jilongda.common.basic.ApiResult; import com.jilongda.common.basic.Constant; import com.jilongda.common.cache.CaffineCache; import com.jilongda.common.security.JwtTokenUtils; import com.jilongda.common.security.SecurityUtils; import com.jilongda.common.swagger.GlobalResultEnum; import com.jilongda.common.utils.ResponseUtils; import com.jilongda.common.exception.ServiceException; import com.jilongda.common.exception.TokenException; import io.jsonwebtoken.Claims; import lombok.extern.slf4j.Slf4j; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.util.Base64Utils; import org.springframework.web.filter.OncePerRequestFilter; import javax.annotation.Resource; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.Objects; /** * 登录认证检查过滤器 * * @author xiaochen * @date Jun 29, 2020 *

* OncePerRequestFilter是在一次外部请求中只过滤一次。对于服务器内部之间的forward等请求,不会再次执行过滤方法。 *

* 文档参见:https://www.jianshu.com/p/b2aa7dd346a2 */ @Slf4j public class AuthenticationFilter extends OncePerRequestFilter { private final SecurityUtils securityUtils; private CaffineCache accessTokenCache; public AuthenticationFilter(SecurityUtils securityUtils) { this.securityUtils = securityUtils; } @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { // 全局异常无法捕捉过滤器异常,需在此处做处理 try { String token = JwtTokenUtils.getToken(request); // 获取摘要信息 Claims claims = JwtTokenUtils.getClaimsFromToken(token); CaffineCache tokenCache = null; if (Objects.nonNull(this.accessTokenCache)) { tokenCache = this.accessTokenCache; } // 如果token被托管 if (Objects.nonNull(tokenCache)) { String accessToken = tokenCache.getKey(Constant.JWT_TOKEN_KEY_PREFIX + claims.getSubject()); if (Objects.isNull(accessToken)) { throw new TokenException(com.jilongda.common.swagger.GlobalResultEnum.TOKEN_EXPIRE.getCode(), com.jilongda.common.swagger.GlobalResultEnum.TOKEN_EXPIRE.getMessage()); } accessToken = new String(Base64Utils.decode(accessToken.getBytes())); if (!token.equals(accessToken)) { throw new TokenException(com.jilongda.common.swagger.GlobalResultEnum.TOKEN_EXPIRE.getCode(), GlobalResultEnum.TOKEN_EXPIRE.getMessage()); } } Authentication authentication = JwtTokenUtils.getAuthenticatione(token); SecurityContextHolder.getContext().setAuthentication(authentication); Object principal = authentication.getPrincipal(); String string = principal.toString(); // SecUser one = secUserService.getOne(Wrappers.lambdaQuery(SecUser.class).eq(SecUser::getPhone, principal.toString())); // securityUtils.checkAuthentication(request); // chain.doFilter(request, response); } catch (Exception e) { // 如果是业务异常,需返回状态码 if (e instanceof ServiceException) { ServiceException e1 = (ServiceException) e; ResponseUtils.renderJson(response, ApiResult.failed(e1.getCode(), e.getMessage())); } else if (e instanceof TokenException) { TokenException e1 = (TokenException) e; ResponseUtils.renderJson(response, ApiResult.failed(e1.getCode(), e.getMessage())); } else { ResponseUtils.renderJson(response, ApiResult.failed(e.getMessage())); } return; } } }