该请求不包含在自定义过滤器中。春季安全

Posted

技术标签:

【中文标题】该请求不包含在自定义过滤器中。春季安全【英文标题】:The request is not included in the custom filter. Spring Security 【发布时间】:2021-08-03 13:27:37 【问题描述】:

大家好,我正在使用 Spring Security 和 JWT 令牌编写身份验证。

我在配置中添加了我自己的过滤器。但该请求不包含在过滤器中。因此,对任何地址的所有请求都会被执行,即使没有令牌。

SecurityConfig.class

@Configuration
@EnableWebSecurity
@ComponentScan("my.pac")
public class SecurityConfig extends WebSecurityConfigurerAdapter 

    @Autowired
    private JwtFilter jwtFilter;

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
                .httpBasic().disable()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/register", "/auth").permitAll()
                .and()
                .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
    

    @Bean
    public PasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    

过滤器

@Component
public class JwtFilter extends GenericFilterBean 

    public static final String AUTHORIZATION = "Authorization";

    @Autowired
    private JwtProvider jwtProvider;

    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException 
        logger.info("do filter...");
        String token = getTokenFromRequest((HttpServletRequest) servletRequest);
        if (token != null && jwtProvider.validateToken(token)) 
            String userLogin = jwtProvider.getLoginFromToken(token);
            CustomUserDetails customUserDetails = customUserDetailsService.loadUserByUsername(userLogin);
            UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(customUserDetails, null, customUserDetails.getAuthorities());
            SecurityContextHolder.getContext().setAuthentication(auth);
        
        filterChain.doFilter(servletRequest, servletResponse);
    

    private String getTokenFromRequest(HttpServletRequest request) 
        String bearer = request.getHeader(AUTHORIZATION);
        if (hasText(bearer) && bearer.startsWith("Bearer ")) 
            return bearer.substring(7);
        
        return null;
    

更新:

此选项也不适用于过滤器:

    @Override
    protected void configure(HttpSecurity http) throws Exception 
        http
                .httpBasic().disable()
                .csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests()
                .antMatchers("/register", "/auth").permitAll()
                .anyRequest().authenticated()
                .and()
                .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);
    

    @Bean
    public PasswordEncoder passwordEncoder() 
        return new BCryptPasswordEncoder();
    

【问题讨论】:

您不需要自定义 jwtfilter,因为 spring security 已经包含一个可以自定义的 jwtfilter。 docs.spring.io/spring-security/site/docs/current/reference/… 【参考方案1】:

您只指定了.antMatchers("/register", "/auth").permitAll(),要强制对其他事物进行身份验证,您必须添加.anyRequest().authenticated() 所以像这样的

@Override
protected void configure(HttpSecurity http) throws Exception 
    http
        .httpBasic().disable()
        .csrf().disable()
        .sessionManagement()
            .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            .and()
        .authorizeRequests()
            .antMatchers("/register", "/auth").permitAll()
            .and()
            .anyRequest().authenticated()
            .and()
        .addFilterBefore(jwtFilter, UsernamePasswordAuthenticationFilter.class);

【讨论】:

感谢您的回复。我也添加了这个,但是过滤器没有捕获请求(( 也许在您的过滤器之前的其他过滤器已经破坏了链条?您确定调用了 UsernamePasswordAuthenticationFilter 而您的过滤器没有调用吗? 如何查看? 在 UsernamePasswordAuthenticationFilter 中设置断点,看看你的代码是否停止。您的过滤器应该在之前,所以如果它达到 UsernamePasswordAuthenticationFilter 配置一定仍然有问题 我设置了 UsernamePasswordAuthenticationFilter 断点,程序并没有停在那里。可能是什么问题?

以上是关于该请求不包含在自定义过滤器中。春季安全的主要内容,如果未能解决你的问题,请参考以下文章

Spring Security getAuthenticationManager() 在自定义过滤器中返回 null

CORS过滤器在春季不起作用

如何在春季测试 LDAP 安全配置?

使用弹簧安全与自定义过滤器的优势?

如何在身份验证之后和注销之前调用方法? (春季安全)

如何在自定义插件开发中显示产品过滤器