一、创建JwtAuthenticationFilter类
@Component
public class JwtAuthenticationFilter extends OncePerRequestFilter {
@Resource
private JwtUtils jwtUtils;
@Resource
private RedisCache redisCache;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
//1、获取token
String token = request.getHeader("token");
if(!StringUtils.hasText(token)){
//放行
filterChain.doFilter(request,response);
//如果不return,那么经过一系列的链条之后,还会运行后面的代码
return;
}
//2、解析token
String userId;
try {
Claims claims = jwtUtils.parseJWT(token);
userId = claims.getSubject();
} catch (Exception error) {
throw new RuntimeException("token异常");
}
//3、从redis中获取用户信息
String redisKey="login:"+userId;
SecurityUser securityUser=redisCache.getCacheObject(redisKey);
if(Objects.isNull(securityUser)){
throw new ServletException("用户未登录");
}
//4、存入SecurityContextHolder
//todo:权限信息还没有
UsernamePasswordAuthenticationToken authentication
= new UsernamePasswordAuthenticationToken(securityUser,null,null);
SecurityContextHolder.getContext().setAuthentication(authentication);
//放行
filterChain.doFilter(request,response);
}
}
二、把JwtAuthenticationFiler添加到过滤器链中
关键代码
//webSecurityConfig
@Resource
private JwtAuthenticationFilter jwtAuthenticationFilter;
@Override
protected void configure(HttpSecurity http) throws Exception {
//添加进过滤器链中
http.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
http.authorizeRequests()
.mvcMatchers("/login") .permitAll()
.anyRequest().permitAll();
http.csrf().disable();
}