记录一个坑

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容器中就可以啦!

以上是关于记录一个坑的主要内容,如果未能解决你的问题,请参考以下文章

Qt QCustomPlot 踩坑记录

Qt QCustomPlot 踩坑记录

记录MySQL创建表的一个坑

记录 PyTorch Lightning 的一个坑

ant design的一个坑记录

Electron踩坑记录