P.19-token认证过滤器代码实现、P.20-配置认证过滤器、P.21-退出登录
P.19-token认证过滤器代码实现
自定义一个过滤器,这个过滤器会去获取请求头中的token,对token进行解析取出其中的userid。
使用userid去redis中获取对应的LoginUser对象。
然后封装Authentication对象存入SecurityContextHolder
@Component public class JwtAuthenticationTokenFilter extends OncePerRequestFilter { @Autowired private RedisCache redisCache; @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { //获取token String token = request.getHeader("token"); if (!StringUtils.hasText(token)) { //放行 filterChain.doFilter(request, response); return; } //解析token String userid; try { Claims claims = JwtUtil.parseJWT(token); userid = claims.getSubject(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("token非法"); } //从redis中获取用户信息 String redisKey = "login:" + userid; LoginUser loginUser = redisCache.getCacheObject(redisKey); if(Objects.isNull(loginUser)){ throw new RuntimeException("用户未登录"); } //存入SecurityContextHolder //TODO 获取权限信息封装到Authentication中 UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser,null,null); SecurityContextHolder.getContext().setAuthentication(authenticationToken); //放行 filterChain.doFilter(request, response); } }
P.20-配置认证过滤器
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { //创建BCryptPasswordEncoder注入容器 @Bean public PasswordEncoder passwordEncoder(){ return new BCryptPasswordEncoder(); } @Autowired private JwtAuthenticationTokenFilter jwtAuthenticationTokenFilter; @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { return super.authenticationManagerBean(); } @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); } }
P.21-退出登录
在LoginController下创建
@PostMapping("/user/logout")//推出 public ResponseResult logout(){ return loginServcie.logout(); }
并实现logout方法
ResponseResult logout();//推出
在LoginServcieImpl中进行实现该方法
@Override public ResponseResult logout() { //获取SecurityContextHolder中的用户id UsernamePasswordAuthenticationToken authentication = (UsernamePasswordAuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); LoginUser loginUser = (LoginUser) authentication.getPrincipal(); Long userid = loginUser.getUser().getId(); //删除Redis中的值 redisCache.deleteObject("login" + userid); return new ResponseResult(200,"注销成功"); }