Spring-CORS无法与Security Config一起使用

时间:2018-12-27 10:50:28

标签: spring spring-security cors spring-webflux

我开发了一个带有spring webflux后端的角度应用程序。到目前为止,CorsFilter可以正常工作,并允许来自前端的请求。

然后我添加了一个SecurityConfig。从那时起,CorsFilter停止工作,我在角度应用程序中遇到了异常:

  

从原点“ http://localhost:8080/users/999/folders/%2F/media/”到“ http://localhost:4200”处对XMLHttpRequest的访问已被CORS策略阻止:对预检请求的响应未通过访问控制检查:否'Access-Control-Allow-原始标头出现在请求的资源上

此过滤器工作正常:

@Configuration
public class CorsFilter {

    private static final String FRONTEND_LOCALHOST = "http://localhost:4200";
    private static final String FRONTEND_STAGING = "https://somehost.github.io";

    @Bean
    CorsWebFilter corsWebFilter() {
        CorsConfiguration corsConfig = new CorsConfiguration();
        corsConfig.applyPermitDefaultValues();
        corsConfig.addAllowedMethod(HttpMethod.PUT);
        corsConfig.addAllowedMethod(HttpMethod.DELETE);
        corsConfig.setAllowedOrigins(Arrays.asList(FRONTEND_LOCALHOST, FRONTEND_STAGING));

        UrlBasedCorsConfigurationSource source =
                new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfig);

        return new CorsWebFilter(source);
    }
}

然后,我使用以下SecurityConfig添加了授权(承载者令牌):

@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfiguration {

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http.cors().and().csrf()
            .csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse())
            .and()
            .authorizeExchange()
            .anyExchange().authenticated()
            .and()
            .oauth2ResourceServer()
            .jwt();
        return http.build();
    }

似乎通过安全配置不再考虑我的CorsFilter。我认为需要在配置中显式添加corsfilter,但是我发现的示例没有用。我希望有人可以提供帮助,并且知道原因。

编辑:为了解决重复问题:我已经尝试将cors()cors().configurationSource(corsConfig())添加到我的安全配置中,但是没有帮助。

2 个答案:

答案 0 :(得分:0)

尝试添加此配置

corsConfig.setAllowCredentials(true);

答案 1 :(得分:0)

我通过实现自定义的corsfilter在Enable CORS in Spring 5 Webflux?中找到了一种可行的方法。

但是,我仍然不满意该解决方案,因为它看起来像是一种解决方法。

最后,我找到了罪魁祸首……一个令人尴尬。我发布的SecurityConfig使用了错误的软件包(偶然是使用默认软件包),因此配置没有被提取。

当我将代码粘贴到securityconfig时,问题的cors过滤器也开始工作。

所以我最终的SecurityConfig看起来像这样:

import java.util.Arrays;

import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.method.configuration.EnableReactiveMethodSecurity;
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity;
import org.springframework.security.config.web.server.ServerHttpSecurity;
import org.springframework.security.web.server.SecurityWebFilterChain;
import org.springframework.security.web.server.csrf.CookieServerCsrfTokenRepository;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.reactive.CorsConfigurationSource;
import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;

@EnableWebFluxSecurity
@EnableReactiveMethodSecurity
public class SecurityConfiguration {

    private static final String FRONTEND_LOCALHOST = "http://localhost:4200";
    private static final String FRONTEND_STAGING = "https://somehost.github.io";

    @Bean
    public SecurityWebFilterChain securityWebFilterChain(ServerHttpSecurity http) {
        http
                .csrf()
                .csrfTokenRepository(CookieServerCsrfTokenRepository.withHttpOnlyFalse())
                .and()
                .authorizeExchange()
                .anyExchange().authenticated()
                .and()
                .oauth2ResourceServer()
                .jwt();
        return http.build();
    }


    @Bean
    CorsConfigurationSource corsConfiguration() {
        CorsConfiguration corsConfig = new CorsConfiguration();
        corsConfig.applyPermitDefaultValues();
        corsConfig.addAllowedMethod(HttpMethod.PUT);
        corsConfig.addAllowedMethod(HttpMethod.DELETE);
        corsConfig.setAllowedOrigins(Arrays.asList(FRONTEND_LOCALHOST, FRONTEND_STAGING));

        UrlBasedCorsConfigurationSource source =
                new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", corsConfig);
        return source;
    }
}