【问题标题】:Spring Security filter chain not ignoring specified path [duplicate]Spring Security过滤器链不忽略指定的路径[重复]
【发布时间】:2018-03-24 19:44:29
【问题描述】:

我有一个通过 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
    }
}

【问题讨论】:

    标签: java spring-mvc spring-security


    【解决方案1】:

    只是一个建议。

    是否有可能,您不是在打身份验证,而是在打 Cors?

    身份验证 - HTTP 状态 401

    CORS - HTTP 状态 403

    如果您启用了 cors 并且未对其进行配置,则它不允许任何跨域请求。 来自 CorsConfiguration javadoc:

    默认情况下,新创建的 CorsConfiguration 不允许任何跨域请求,并且必须明确配置以指示应允许的内容。

    【讨论】:

    • 抱歉,我实际上在另一个类中有一个 cors 配置 bean,它现在允许从所有映射访问。应该提供。
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 2022-01-25
      • 2016-10-26
      • 1970-01-01
      • 1970-01-01
      • 2018-07-08
      • 2017-01-02
      • 2020-11-04
      • 1970-01-01
      • 2017-05-19
      相关资源
      最近更新 更多