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;
}
}
}