实现拦截器
有图片可知,在上篇文章我们重写了UserDetailsManager,现在我们来进行之后的操作
在UserDetailsManager中我们可以调动数据库去进行一个账号密码的校验
之后我们这样设置拦截器进行一个token获取存储在usernamePasswordAuthenticationFilter这一层中,
有,则存储在SecurityContextHolder.getContext()中供接下来的调用,没有就放行
@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
@Autowired
private RedisCache redisCache;
@Override
protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {
String token = httpServletRequest.getHeader("token");
if(!StringUtils.hasText(token)){
filterChain.doFilter(httpServletRequest,httpServletResponse);
return;
}
String userId="";
try {
Claims claims = JwtUtil.parseJWT(token);
userId = claims.getSubject();
} catch (Exception e) {
throw new RuntimeException(e);
}
LoginUser cacheObject = redisCache.getCacheObject("login:" + userId);
if(Objects.nonNull(cacheObject)){
UsernamePasswordAuthenticationToken token1=new UsernamePasswordAuthenticationToken(cacheObject,null,null);
SecurityContextHolder.getContext().setAuthentication(token1);
}
filterChain.doFilter(httpServletRequest,httpServletResponse);
}
}
启用拦截器
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Autowired
private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter;
@Bean
public BCryptPasswordEncoder passwordEncoder(){
return new BCryptPasswordEncoder();
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
//关闭csrf
.csrf().disable()
//不通过Session获取SecurityContext
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
.and()
.authorizeRequests()
// 对于登录接口 允许匿名访问
.antMatchers("/user/login").anonymous()
// 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated();
http.addFilterBefore(jwtAuthenticationTokenFilter, UsernamePasswordAuthenticationFilter.class);
}
@Bean
@Override
public AuthenticationManager authenticationManagerBean() throws Exception {
return super.authenticationManagerBean();
}
}
```,
注意:
1.不用去想着token没有的情况,由以上逻辑可以看出来,我们将token获取后会存入 SecurityContextHolder中,之后的内置拦截器会检测是否有token,没有就报错,不用自己设置监测
2.其次,一定要注意,在拦截器中放生login接口
3.登录前UsernamePasswordAuthenticationToken存的是账号密码,登录后转入 SecurityContextHolder时,存的是对象
标签:httpServletRequest,拦截器,实现,userId,SecurityContextHolder,SpringSecurity,token,publ
From: https://www.cnblogs.com/fubai/p/18440505