记录一个坑
Posted yyznl
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了记录一个坑相关的知识,希望对你有一定的参考价值。
在做spring security JWT登录验证的时候写了一个filter
public class JwtAuthenticationTokenFilter extends BasicAuthenticationFilter @Value("$token.header") private String token_header; @Autowired private UserDetailsServiceImpl userDetailsService; @Autowired private TokenUtils jwtUtils; public JwtAuthenticationTokenFilter(AuthenticationManager authenticationManager) super(authenticationManager); @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException /* if (request.getMethod().equals(String.valueOf(RequestMethod.GET))) chain.doFilter(request, response); return; */ String auth_token = request.getHeader(this.token_header); final String auth_token_start = "Bearer "; if (!StringUtils.isEmpty(auth_token) && auth_token.startsWith(auth_token_start)) auth_token = auth_token.substring(auth_token_start.length()); else // 不按规范,不允许通过验证 auth_token = null; String username = jwtUtils.getUsernameFromToken(auth_token); logger.info(String.format("Checking authentication for user %s.", username)); // 如果上面解析 token 成功并且拿到了 username 并且本次会话的权限还未被写入 if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) // User user = jwtUtils.getUserFromToken(auth_token); // 用 UserDetailsService 从数据库中拿到用户的 UserDetails 类 // UserDetails 类是 Spring Security 用于保存用户权限的实体类 UserDetails userDetails = userDetailsService.loadUserByUsername(username); // 检查用户带来的 token 是否有效 // 包括 token 和 userDetails 中用户名是否一样, token 是否过期, token 生成时间是否在最后一次密码修改时间之前 // 若是检查通过 if (jwtUtils.validateToken(auth_token, userDetails)) // 生成通过认证 UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userDetails, null, userDetails.getAuthorities()); authentication.setDetails(new WebAuthenticationDetailsSource().buildDetails(request)); logger.info(String.format("Authenticated user %s, setting security context", username)); // 将权限写入本次会话 SecurityContextHolder.getContext().setAuthentication(authentication); chain.doFilter(request, response);
当时的tokenUtils与userDetailServiceImp注入不进来,一直为空
@Configuration @EnableWebSecurity public class WebSecurityConfig extends WebSecurityConfigurerAdapter @Autowired private UserDetailsServiceImpl userDetailsService; @Autowired private JwtLoginFilter jwtLoginFilter; @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception return super.authenticationManagerBean(); @Bean public BCryptPasswordEncoder bCryptPasswordEncoder() return new BCryptPasswordEncoder(); @Override protected void configure(AuthenticationManagerBuilder auth) throws Exception auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder()); @Override protected void configure(HttpSecurity http) throws Exception http .authorizeRequests() .antMatchers("/task/**").authenticated() // 需携带有效 token /* .antMatchers("/admin").hasAuthority("admin") // 需拥有 admin 这个权限 .antMatchers("/ADMIN").hasRole("ADMIN") // 需拥有 ADMIN 这个身份*/ .anyRequest().permitAll() .and() .csrf() .disable() // 禁用 Spring Security 自带的跨域处理 .sessionManagement() // 定制我们自己的 session 策略 .sessionCreationPolicy(SessionCreationPolicy.STATELESS)// 调整为让 Spring Security 不创建和使用 session
.and()
.addFilter(new JwtLoginFilter(authenticationManagerBean()))
.addFilter(new JwtAuthenticationTokenFilter(authenticationManagerBean()));
在websecurityconfig这里addfFilter当时直接new了一个对象放进去的,原来就是因为是new的对象并不在spring容器里,所以注入不进去。
@Autowired注入Spring Bean,则当前类必须也是Spring Bean才能调用它,不能用new xxx()来获得对象,这种方式获得的对象无法调用@Autowired注入的Bean。
后来直接改用@bean的或者直接加@component注解的方式将自定义filter加入到spring容器中就可以啦!
以上是关于记录一个坑的主要内容,如果未能解决你的问题,请参考以下文章