在做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容器中就可以啦!
原文地址:https://www.cnblogs.com/yyZNL/p/11576058.html
时间: 2024-11-05 12:24:36