package com.panzhihua.zuul.filters;
|
|
import com.alibaba.fastjson.JSONArray;
|
import com.alibaba.fastjson.JSONObject;
|
import com.panzhihua.common.constants.*;
|
import com.panzhihua.common.model.vos.LoginUserInfoVO;
|
import com.panzhihua.common.model.vos.R;
|
import com.panzhihua.common.service.user.UserService;
|
import com.panzhihua.common.utlis.AES;
|
import com.panzhihua.common.utlis.JWTTokenUtil;
|
import com.panzhihua.common.utlis.ResultUtil;
|
import io.jsonwebtoken.Claims;
|
import org.springframework.context.ApplicationContext;
|
import org.springframework.data.redis.core.StringRedisTemplate;
|
import org.springframework.data.redis.core.ValueOperations;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.stereotype.Component;
|
import org.springframework.util.ObjectUtils;
|
import org.springframework.web.context.support.WebApplicationContextUtils;
|
|
import javax.servlet.*;
|
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletResponse;
|
import java.io.IOException;
|
import java.util.ArrayList;
|
import java.util.List;
|
import java.util.concurrent.TimeUnit;
|
|
/**
|
* @program: springcloud_k8s_panzhihuazhihuishequ
|
* @description: token校验
|
* @author: huang.hongfa weixin hhf9596 qq 959656820
|
* @create: 2020-11-25 16:35
|
**/
|
@Component
|
public class JWTAuthenticationTokenFilter implements Filter {
|
private StringRedisTemplate stringRedisTemplate;
|
private UserService userService;
|
|
|
@Override
|
public void init(FilterConfig filterConfig) throws ServletException {
|
|
}
|
|
/**
|
* 用户是否登录校验
|
*
|
* @param servletRequest 请求
|
* @param servletResponse 返回
|
* @param filterChain 过滤器链条
|
* @throws IOException io
|
* @throws ServletException servlet
|
*/
|
@Override
|
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
|
HttpServletRequest request = (HttpServletRequest) servletRequest;
|
HttpServletResponse response = (HttpServletResponse) servletResponse;
|
ServletContext context = request.getServletContext();
|
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context);
|
stringRedisTemplate=ctx.getBean(StringRedisTemplate.class);
|
ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
|
userService=ctx.getBean(UserService.class);
|
String requestURI = request.getRequestURI();
|
boolean login = requestURI.contains("login");
|
boolean doc = requestURI.contains("doc.html");
|
boolean css = requestURI.contains(".css");
|
boolean js = requestURI.contains(".js");
|
boolean ui = requestURI.contains("/ui");
|
boolean swagger = requestURI.contains("swagger");
|
boolean ico = requestURI.contains(".ico");
|
boolean docs = requestURI.contains("-docs");
|
boolean error = requestURI.contains("error");
|
boolean useragreement = requestURI.contains("useragreement");
|
boolean refreshToken = requestURI.contains("refreshToken");
|
boolean logout = requestURI.contains("logout");
|
boolean wxPay = requestURI.contains("wxNotify");
|
SafeboxRequestWrapper safeboxRequestWrapper = new SafeboxRequestWrapper(request);
|
if (login||doc||css||js||ui||swagger||ico||docs||error||refreshToken||useragreement||wxPay) {
|
//什么也不做
|
} else {
|
// 获取请求头中JWT的Token
|
String tokenHeader = request.getHeader(TokenConstant.TOKEN_HEADER);
|
if (null != tokenHeader && tokenHeader.startsWith(TokenConstant.TOKEN_PRE)) {
|
// token过期
|
String token = tokenHeader.replace(TokenConstant.TOKEN_PRE, "");
|
Boolean hasKey = stringRedisTemplate.hasKey(UserConstants.LOGOUT_TOKEN + token);
|
if (hasKey) {
|
ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "用户已经登出"));
|
return;
|
}
|
Boolean expired = JWTTokenUtil.isTokenExpired(token);
|
if (expired) {
|
if (logout) {
|
ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "登出成功"));
|
} else {
|
ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "token过期"));
|
}
|
return;
|
}
|
// token解析
|
Claims claims = JWTTokenUtil.getClaimsFromToken(token);
|
if (ObjectUtils.isEmpty(claims)) {
|
ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "token校验失败"));
|
return;
|
}
|
String username = claims.getSubject();
|
int type = (Integer) claims.get("type");
|
if (ObjectUtils.isEmpty(username)) {
|
ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "token校验失败"));
|
return;
|
}
|
List<SimpleGrantedAuthority> authorities = new ArrayList<>();
|
List<SimpleGrantedAuthority> authorities1 = new ArrayList<>();
|
String key = SecurityConstants.ROLE_USER + username;
|
Boolean aBoolean = stringRedisTemplate.hasKey(key);
|
if (1 == type) {//小程序用户统一角色
|
authorities.add(new SimpleGrantedAuthority(SecurityConstants.ROLE_APPLETS));
|
} else {
|
if (aBoolean) {
|
String roles = valueOperations.get(key);
|
authorities = JSONArray.parseArray(roles, SimpleGrantedAuthority.class);
|
} else {
|
R<List<String>> r = userService.getUserRoles(username);
|
List<String> data =(List<String>)r.getData();
|
if (!ObjectUtils.isEmpty(data)) {
|
data.forEach(s -> {
|
authorities1.add(new SimpleGrantedAuthority(s));
|
});
|
authorities = authorities1;
|
valueOperations.set(key, JSONArray.toJSONString(authorities), 24, TimeUnit.HOURS);
|
}
|
}
|
}
|
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(username, username, authorities);//主要使用权限 账户 密码 不重要
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
safeboxRequestWrapper.addHeader(TokenConstant.TOKEN_LOGOUT,tokenHeader);
|
//登录用户的所有信息
|
String userKey = UserConstants.LOGIN_USER_INFO + username;
|
Boolean hasKeyLoginUserInfo = stringRedisTemplate.hasKey(userKey);
|
if(hasKeyLoginUserInfo){
|
String userInfo = valueOperations.get(userKey);
|
byte[] encrypt = AES.encrypt(userInfo, Constants.AES_KEY);
|
String hexStr = AES.parseByte2HexStr(encrypt);
|
safeboxRequestWrapper.addHeader(TokenConstant.TOKEN_USERINFO, hexStr);
|
}else{
|
R<LoginUserInfoVO> r = userService.getUserInfoByUserId(username);
|
if (!R.isOk(r)) {
|
ResultUtil.responseJson(response, R.fail(HttpStatus.ERROR, "登录用户信息查询失败"));
|
return;
|
}
|
LoginUserInfoVO data = r.getData();
|
String userInfo = JSONObject.toJSONString(data);
|
valueOperations.set(userKey,userInfo,24,TimeUnit.HOURS);
|
byte[] encrypt = AES.encrypt(userInfo, Constants.AES_KEY);
|
String hexStr = AES.parseByte2HexStr(encrypt);
|
safeboxRequestWrapper.addHeader(TokenConstant.TOKEN_USERINFO,hexStr );
|
}
|
} else {
|
ResultUtil.responseJson(response, R.fail(HttpStatus.UNAUTHORIZED, "token校验失败"));
|
return;
|
}
|
}
|
filterChain.doFilter(safeboxRequestWrapper,response);
|
}
|
|
@Override
|
public void destroy() {
|
|
}
|
}
|