package com.vincent.rsf.server.common.security;
|
|
import com.vincent.rsf.framework.common.Cools;
|
import com.vincent.rsf.server.common.config.ConfigProperties;
|
import com.vincent.rsf.server.common.constant.Constants;
|
import com.vincent.rsf.server.common.utils.CommonUtil;
|
import com.vincent.rsf.server.common.utils.JwtUtil;
|
import com.vincent.rsf.server.system.entity.Menu;
|
import com.vincent.rsf.server.system.entity.User;
|
import com.vincent.rsf.server.system.entity.UserLogin;
|
import com.vincent.rsf.server.system.service.UserLoginService;
|
import com.vincent.rsf.server.system.service.UserService;
|
import io.jsonwebtoken.Claims;
|
import io.jsonwebtoken.ExpiredJwtException;
|
import lombok.extern.slf4j.Slf4j;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.stereotype.Component;
|
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.ArrayList;
|
import java.util.Date;
|
import java.util.List;
|
import java.util.stream.Collectors;
|
|
/**
|
* 处理携带token的请求过滤器
|
*
|
*/
|
@Slf4j
|
@Component
|
public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|
public static final ArrayList<String> WHITE_KEY = new ArrayList<String>(){
|
private static final long serialVersionUID = 1L;
|
{
|
add("xltys1995");
|
}
|
};
|
|
@Resource
|
private ConfigProperties configProperties;
|
@Resource
|
private UserService userService;
|
@Resource
|
private UserLoginService userLoginService;
|
|
@Override
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
|
String access_token = JwtUtil.getAccessToken(request);
|
for (String filterPath : SecurityConfig.FILTER_PATH) {
|
AntPathRequestMatcher antPathMatcher = new AntPathRequestMatcher(filterPath);
|
if (antPathMatcher.matches(request)) {
|
access_token = "";
|
}
|
}
|
if (!Cools.isEmpty(access_token)) {
|
try {
|
User user;
|
if (WHITE_KEY.contains(access_token)) {
|
user = userService.getByUsername("root", 1L);
|
if (user == null) {
|
throw new UsernameNotFoundException("Username not found");
|
}
|
userService.setUserAuthInfo(user);
|
List<Menu> authorities = user.getAuthorities().stream()
|
.filter(m -> !Cools.isEmpty(m.getAuthority())).collect(Collectors.toList());
|
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
user, null, authorities);
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
} else {
|
// 解析token
|
Claims claims = JwtUtil.parseToken(access_token, configProperties.getTokenKey());
|
JwtSubject jwtSubject = JwtUtil.getJwtSubject(claims);
|
user = userService.getByUsername(jwtSubject.getUsername(), jwtSubject.getTenantId());
|
if (user == null) {
|
throw new UsernameNotFoundException("Username not found");
|
}
|
userService.setUserAuthInfo(user);
|
List<Menu> authorities = user.getAuthorities().stream()
|
.filter(m -> !Cools.isEmpty(m.getAuthority())).collect(Collectors.toList());
|
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(
|
user, null, authorities);
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
// token将要过期签发新token, 防止突然退出登录
|
long expiration = (claims.getExpiration().getTime() - new Date().getTime()) / 1000 / 60;
|
if (expiration < configProperties.getTokenRefreshTime()) {
|
String token = JwtUtil.buildToken(jwtSubject, configProperties.getTokenExpireTime(),
|
configProperties.getTokenKey());
|
response.addHeader(Constants.TOKEN_HEADER_NAME, token);
|
userLoginService.saveAsync(user.getId(), token, UserLogin.TYPE_REFRESH, user.getTenantId(), null, request);
|
}
|
}
|
} catch (ExpiredJwtException e) {
|
log.error("JwtAuthenticationFilter ExpiredJwtException", e);
|
CommonUtil.responseError(response, Constants.TOKEN_EXPIRED_CODE, Constants.TOKEN_EXPIRED_MSG,
|
e.getMessage());
|
return;
|
} catch (Exception e) {
|
log.error("JwtAuthenticationFilter", e);
|
CommonUtil.responseError(response, Constants.BAD_CREDENTIALS_CODE, Constants.BAD_CREDENTIALS_MSG,
|
e.toString());
|
return;
|
}
|
}
|
chain.doFilter(request, response);
|
}
|
|
}
|