【问题标题】:CORS interfering with Spring Security oauth2CORS 干扰 Spring Security oauth2
【发布时间】:2017-11-09 15:56:20
【问题描述】:

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

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

如果我启用 CORS,预检会成功,但现在我收到 InsufficientAuthenticationException,说 “没有客户端身份验证。尝试添加适当的身份验证过滤器”。据我所知,这是因为 Spring Security 无法从请求中获取主体。

有人对如何处理这个问题有建议吗?

【问题讨论】:

  • 当您从其他域发送请求时,CORS 会阻止 OPTIONS 的飞行前请求。所以在你的控制器代码中添加@CrossOrigin@RestController并检查一次。
  • @Hema 是的,这是我的问题,当我添加 CORS(在每个端点上)时,我得到了 InsufficientAuthenticationException。我应该添加一个 @RestController 包含 spring 自动创建的 oauth 端点,还是会覆盖 spring 安全性?
  • 不,那不会超车。只需添加@RestController 并尝试一次。这对我来说很好。所以建议你

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


【解决方案1】:

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

这是我的 CORS 专用配置类(改编自官方 spring 指南,我稍后会对其进行调整)

@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;
    }
}

【讨论】:

  • 我使用的是 spring 4.3 版本,您的代码在我的情况下显示错误,例如 FilterRegistrationBean 无法解析为类型。
  • @sireeshaj 自发布以来我基本上没有接触过这段代码,它仍在工作。我刚刚将方法名称从corsFilter 更改为customCorsFilter,因为spring 抱怨(因为spring boot 已经用该名称定义了自己的bean),也许试试?否则我的代码看起来像上面的代码,并且在 spring boot 1.5.12 上运行良好(使用 spring 4.3.16)
  • 对于这个问题,我必须至少查看 20 个不同的“答案”,其中包含您发布的答案的多个版本。他们中没有一个人使用 bea,.setOrder(Ordered.HIGHEST_PRECEDENCE) 这正是我的问题。我花了几个小时才得到你的答案,但我很高兴我找到了它。谢谢!
  • @spetz83 很好,我已经忘记了那个细节的重要性,但它确实是 sn-p 中最关键的部分。我已经更新了强调这一事实的答案,谢谢
  • 你先生!我也搜索了一半的互联网,最后。非常感谢。
【解决方案2】:

如果您使用的是 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;
    }
}

【讨论】:

    猜你喜欢
    • 2019-09-25
    • 2016-04-20
    • 2016-06-25
    • 2015-11-22
    • 2018-09-20
    • 2017-11-21
    • 2016-07-04
    • 2020-05-31
    • 2019-04-29
    相关资源
    最近更新 更多