自定义Spring Security过滤器 JwtAuthenticationTokenFilter
闪送平台项目filter
包下JwtAuthenticationTokenFilter
类
在spring-security原本的FilterChain中, 添加 jwt认证用的Filter :JwtAuthenticationTokenFilter。
放在所有过滤器前面,检查浏览器携带的token是否合法
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired
StringRedisTemplate stringRedisTemplate;
// 用于在线程本地存储用户的ID信息。这样,同一线程中的其他组件,比如其他过滤器或拦截器,都能够方便地获取到用户的ID信息。
public static ThreadLocal<Long> threadLocal = new ThreadLocal<>();
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//获取token
String accessToken = request.getHeader(KeyProperties.TOKEN_HEADER);
if (StringUtils.isEmpty(accessToken)) {
filterChain.doFilter(request, response);
//加return为了返回时第二次经过过滤器不再执行下面的代码
return;
}
if (accessToken.startsWith("Bearer ")) {
accessToken = accessToken.substring(7);
}
//解析token
String userId = "";
Claims claims = null;
try {
claims = JwtUtil.parseJWT(accessToken);
} catch (Exception e) {
throw new BizException(ErrorCode.TOKEN_PARSE_ERROR);
}
userId = claims.getSubject();
//从redis获取用户信息
String key = KeyProperties.TOKEN_PREFIX + userId;
String userInfo = stringRedisTemplate.opsForValue().get(key);
UserPermission userPermission = JSONObject.parseObject(userInfo, UserPermission.class);
if (userPermission == null) {
throw new BizException(ErrorCode.TOKEN_PARSE_ERROR);
}
//存入SecurityContextHolder
// 获取权限信息封装到authticationToken中
UsernamePasswordAuthenticationToken authenticationToken =
new UsernamePasswordAuthenticationToken(userPermission, null, null);
SecurityContextHolder.getContext().setAuthentication(authenticationToken);
//存入ThreadLocal
threadLocal.set(Long.valueOf(userId));
//放行
filterChain.doFilter(request, response);
}
}
这个过滤器的作用是在请求到达时验证 JWT,并将用户信息存储到 Spring Security 的上下文和 ThreadLocal 中,方便后续的权限验证和用户信息获取。