【问题标题】:CORS not working in a project where both ResourceServerConfigurerAdapter and WebSecurityConfigurerAdapter is presentCORS 在同时存在 ResourceServerConfigurerAdapter 和 WebSecurityConfigurerAdapter 的项目中不起作用
【发布时间】:2021-02-24 17:47:34
【问题描述】:

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

我查看了项目(这是一个捆绑为耳朵而不是引导的 Spring 5 项目)发现有一个 CORS 过滤器。然后我查看了安全配置,发现有两个。

//@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 的优先级,它将解决问题。如果我在这里误解了任何内容,请为我解决。

【问题讨论】:

    标签: spring rest spring-security spring-oauth2


    【解决方案1】:

    我也遇到了同样的问题!

    所以我做了什么,我只是隐式地交换了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);
        }
    }
    

    【讨论】:

    • 这样工作吗?因为除了跳过安全检查服务器需要设置某些响应头,比如允许的来源等
    • 我是这么说的!只需跳过 OPTIONS 请求,因为 OPTIONS 请求不会带上您的 Auth 参数,例如一些包含 Auth token 或任何其他参数的 headers。所以只需跳过OPTIONS 请求,然后捕获另一个请求,然后应用安全方面
    猜你喜欢
    • 2023-03-25
    • 1970-01-01
    • 2016-06-10
    • 2017-05-28
    • 2021-03-06
    • 2020-11-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-13
    相关资源
    最近更新 更多