Spring Security过滤器链不会忽略指定的路径

问题描述

感谢@dur询问我是否正在使用Spring Boot,这使我找到了解决方案。

这使我开始考虑Spring Boot如何自动为我们自动创建bean,最终成为这里的罪魁祸首。事实证明,我的JwtAuthenticationFilter类是由Spring Boot自动放入过滤器链中的,但是当我在安全配置中显式声明它时,它也被包含在安全过滤器链中。因此,尽管我正确地排除/auth/tokenignoring()安全性配置中的方法,但这还不足以阻止过滤器在Spring Boot本身的上下文中发生。解决方案是配置一个显式阻止Spring Boot添加它的bean。

@Bean
public RegistrationBean jwtAuthFilterRegister(JwtAuthenticationFilter filter) {
    FilterRegistrationBean registrationBean = new FilterRegistrationBean(filter);
    registrationBean.setEnabled(false);
    return registrationBean;
}

解决方法

我有一个通过JWT进行身份验证的Spring Boot REST API。我的问题是,我已将Spring
Security配置为允许无限制地访问用于身份验证的路径/auth/token,但是当它不应该被访问时,它仍然会击中我的安全过滤器。不知道我在哪里错了,任何建议都非常适合

安全配置

public class JwtWebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JwtAuthenticationEntryPoint unauthorizedHandler;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) 
        throws Exception {
        authenticationManagerBuilder
                .userDetailsService(this.userDetailsService)
                .passwordEncoder(passwordEncoder());
    }

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

    @Bean
    public JwtAuthenticationFilter authenticationTokenFilter() throws Exception {
        return new JwtAuthenticationFilter();
    }

    @Override
    protected void configure(HttpSecurity httpSecurity) throws Exception {
        httpSecurity
            .authorizeRequests()
            .antMatchers("/auth/token").permitAll() // do not authenticate
            .anyRequest().authenticated()

            // TODO: configure
            .cors()
            .and()

            // TODO enable and configure
            .csrf().disable()

            // Unauthorized request handler
            .exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and()

            // Keep application security stateless
            .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);

        // JWT security filter
        httpSecurity.addFilterBefore(authenticationTokenFilter(),UsernamePasswordAuthenticationFilter.class);

        // Disable page caching to prevent cached REST responses
        httpSecurity.headers().cacheControl();
    }

    @Override
    public void configure(WebSecurity webSecurity) throws Exception {
        webSecurity.ignoring().antMatchers(HttpMethod.POST,"/auth/token");
    }
}

过滤器

public class JwtAuthenticationFilter extends OncePerRequestFilter {
    @Override
    protected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws ServletException,IOException {
        // this runs
    }
}

控制器

@RestController
public class AuthenticationController {

    // Authenticate user
    @RequestMapping(value = "/auth/token",method = RequestMethod.POST)
    public ResponseEntity<?> createAuthenticationToken(HttpServletResponse response,@RequestBody JwtAuthenticationRequest authenticationRequest,Device device) throws AuthenticationException {
        // never gets to run
    }
}

猜你在找的技术问答相关文章

如何检查配对的蓝牙设备是打印机还是扫描仪(Android)
是否允许实体正文进行HTTP DELETE请求?
如何将ZipInputStream转换为InputStream?
java.util.logging Java 8中的变量
PowerMockito.doReturn返回null
Java中的RESTful调用
Swing / Java:如何正确使用getText和setText字符串
特殊字符和重音字符
Android Studio中的ndk.dir错误
错误“找不到主类”