首页 > 解决方案 > 使用弹簧安全性在后端启用 CORS 的正确方法是什么。在 REST 框架的项目中也使用 Apache cxf

问题描述

我有以下代码片段(以及其他一些配置)。还应该做些什么?来自 chrome 的错误是:“对预检请求的响应未通过访问控制检查:请求的资源上不存在‘Access-Control-Allow-Origin’标头。”

SC: 来自 rxjs(Using angular) 调用的页面的 ResponseHeaders 的屏幕截图

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
protected  class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .cors().and()
        .csrf().disable()
        .anonymous().disable()
        .authorizeRequests()
        .antMatchers(HttpMethod.OPTIONS,"/oauth/token").permitAll();
    }
@Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    protected CorsConfigurationSource corsConfigurationSource()
    {
        CorsConfiguration configuration = new CorsConfiguration();
        configuration.setAllowCredentials(true);
        configuration.setMaxAge((long) 3600);
        configuration.addAllowedOrigin("*");
        //configuration.setAllowedOrigins(Arrays.asList("*"));
        configuration.setAllowedMethods(Arrays.asList("*"));
        //configuration.setAllowedMethods(Arrays.asList("GET","POST","OPTIONS", "DELETE"));
        configuration.setAllowedHeaders(Arrays.asList("*"));
        //configuration.setAllowedHeaders(Arrays.asList( "x-requested-with","X-requested-with", "authorization", "cache-control", "Content-Type,adminUserId"));
        configuration.setExposedHeaders(Arrays.asList("Access-Control-Allow-Origin","Access-Control-Allow-Credentials"));
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", configuration);

        return source;
    }
}
@Configuration
@EnableResourceServer
protected class ResourceServer extends ResourceServerConfigurerAdapter {

    @Autowired
    @Qualifier("dataSource")
    DataSource dataSource;

    @Bean
    public TokenStore tokenStore() {
        return new JdbcTokenStore(dataSource);
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {         
        http
        .anonymous().disable()
        .requestMatchers().antMatchers("/rest/services/messagePosting/**")
        .and().authorizeRequests()
        .antMatchers("/rest/services/messagePosting/**")
        .authenticated()
        .and().exceptionHandling().accessDeniedHandler(new OAuth2AccessDeniedHandler());     
    }

    @Override
    public void configure(ResourceServerSecurityConfigurer resources)
            throws Exception {
        resources.resourceId("my-rest-services");
    }
}

标签: springrestspring-securitycorscxf

解决方案


更新:此解决方案仅适用于 Spring-boot。
不记得确切的场景,但我想是在 OAuth2 配置中,当我在扩展配置类中配置 CORS 时遇到了类似的问题WebSecurityConfigurerAdapter,但这没有帮助。
我找到的解决方案是在一个单独的 java 类中配置 CORS,并将该类导入您的 spring 安全配置类。如下所示:

@Configuration
public class CorsConfig {   

    @Bean
    public FilterRegistrationBean<Filter> customCorsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<Filter> bean = new FilterRegistrationBean<Filter>(new CorsFilter(source));
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }
}

您的安全配置类(注意导入注释):

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true, proxyTargetClass = true)
@Import({CorsConfig.class})
protected  class OAuth2SecurityConfiguration extends WebSecurityConfigurerAdapter {
@Override
    protected void configure(HttpSecurity http) throws Exception {
        http
        .cors().and()
        .csrf().disable()
        .anonymous().disable()
        .authorizeRequests()
        .antMatchers(HttpMethod.OPTIONS,"/oauth/token").permitAll();
    }

推荐阅读