CORS干扰Spring Security oauth2

时间:2017-06-08 05:16:34

标签: javascript java spring spring-security oauth-2.0

我在尝试从浏览器中获取来自 oauth / token 的令牌时遇到问题。我有Spring Security和Spring Security oauth的Spring Boot应用程序,我正在尝试从不同端口的javascript SPA进行身份验证。

当在后端禁用CORS时,我可以使用邮递员或终端从oauth端点获取令牌没问题,但是由于CORS预检失败,我无法从javascript获取它们。

如果我启用了CORS,则预检成功,但现在我得到InsufficientAuthenticationException“没有客户端身份验证。尝试添加适当的身份验证过滤器”。从我可以收集的内容来看,这是因为Spring Security无法从请求中获取主体。

有没有人建议如何处理这个?

2 个答案:

答案 0 :(得分:16)

显然,在进入Spring Security过滤器链之前会对Oauth2端点和过滤器进行处理,因此添加CORS过滤器通常不会起作用,但添加具有高阶优先级的CORS过滤器bean最终会起作用。

这是我对CORS的专用配置类(改编自官方春季指南,我将在稍后进行调整)

@Configuration
public class CorsConfig {
//IMPORTANT: it has to be a normal configuration class, 
//not extending WebMvcConfigurerAdapter or other Spring Security class
    @Bean
    public FilterRegistrationBean customCorsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("http://localhost:3000");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));

        //IMPORTANT #2: I didn't stress enough the importance of this line in my original answer, 
        //but it's here where we tell Spring to load this filter at the right point in the chain
        //(with an order of precedence higher than oauth2's filters)
        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }
}

答案 1 :(得分:1)

如果您使用的是Spring boot 2,只需更新SrThompson的响应,类FilterRegistrationBean就很通用了。

所以代码看起来像这样:

@Configuration
public class CorsConfig {

    @Bean
    public FilterRegistrationBean<CorsFilter> customCorsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.setAllowedMethods(Collections.singletonList("*"));
        config.setAllowedHeaders(Collections.singletonList("*"));
        config.addAllowedOrigin("http://localhost:3000");
        config.addAllowedOrigin("http://production.url");
        config.setAllowCredentials(true);
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean<CorsFilter> bean = new FilterRegistrationBean<>(new CorsFilter(source));

        bean.setOrder(Ordered.HIGHEST_PRECEDENCE);
        return bean;
    }
}