CORS在同时存在ResourceServerConfigurerAdapter和WebSecurityConfigurerAdapter的项目中不起作用

问题描述

我遇到了这个项目,目的是解决服务器未响应 OPTIONS 请求而将 401 响应的问题。

我查看了该项目,并发现它是一个CORS过滤器(这是一个Spring 5项目,它作为耳朵而不是靴子捆绑在一起)。然后我查看了安全配置,发现有两个。

//@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private CustomUserDetailsService customUserDetailsService;

    @Bean
    public CustomDaoAuthenticationProvider authenticationProvier() {
        CustomDaoAuthenticationProvider customProvider = new CustomDaoAuthenticationProvider();
        customProvider.setUserDetailsService(customUserDetailsService);
        customProvider.setPasswordEncoder(passwordEncoder());
        return customProvider;
    }

    @Override
    public void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.authenticationProvider(authenticationProvier());

    }

    @Override
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }

    @Override
    protected void configure(final HttpSecurity http) throws Exception {
        http
                .cors()
                .and()
                .csrf().disable()
                .anonymous().disable()
                .authorizeRequests()
                .antMatchers("/**").permitAll();
    }

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

}

第二个是

@Configuration
@EnableResourceServer
@EnableWebSecurity
public class OAuth2ResourceServerConfig extends ResourceServerConfigurerAdapter {

    @Override
    public void configure(final HttpSecurity http) throws Exception {

        http.anonymous().disable().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .csrf().disable().authorizeRequests()

                .antMatchers(HttpMethod.GET,"/somepath/**").access("#oauth2.hasScope('some_scope') "
                + "and hasAnyRole('role_1','r')")
                ....
                .anyRequest().authenticated();
    }

    @Override
    public void configure(final ResourceServerSecurityConfigurer config) {
        config.tokenServices(tokenServices());
    }

    @Bean
    public TokenStore tokenStore() {
        return new JwtTokenStore(accesstokenConverter());
    }

    @Bean
    public JwtAccesstokenConverter accesstokenConverter() {
        final JwtAccesstokenConverter converter = new JwtAccesstokenConverter();

        ClassPathResource resource = new ClassPathResource("id_rsa.pub");
        String publicKey = null;
        try {
            publicKey = new String(FilecopyUtils.copyToByteArray(resource.getInputStream()));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        converter.setVerifierKey(publicKey);
        return converter;
    }

    @Bean
    @Primary
    public DefaultTokenServices tokenServices() {
        final DefaultTokenServices defaultTokenServices = new DefaultTokenServices();
        defaultTokenServices.setTokenStore(tokenStore());
        return defaultTokenServices;
    }

}

在阅读了与此相关的问题之后,我发现OAuth2ResourceServerConfig的优先级高于WebSecurityConfig(问题here)。

那么在当前集中是否同时检查令牌和密码? 如果增加WebSecurityConfig的优先级,它将解决此问题。如果我误解了这里的任何内容,请为我修复。

解决方法

我也面临着同样的问题!

所以我所做的只是隐式交换了OPTIONS请求。因为“可选请求”只是从浏览器到服务器,以检查Service是否正常工作。

如果您注意到,当我们从POSTMAN测试端点时,此问题就不会消失。

所以我做了

@Component
public class SecretKeyFilter implements WebFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange,WebFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();

        if(!request.getMethod().name().equals("OPTIONS"))
        {
            
          /**
           * Do the authentication and valication of your request here.
           *
          **/
        }

        return chain.filter(exchange);
    }
}