当我期望它时,CORS 的 Spring 实现不会拒绝消息
Posted
技术标签:
【中文标题】当我期望它时,CORS 的 Spring 实现不会拒绝消息【英文标题】:Spring implementation of CORS is not rejecting messages when I expected it to 【发布时间】:2019-04-25 03:46:37 【问题描述】:我的 maven 项目中有一个带有 Spring @RestController 注释的 Web 服务,我想向它添加 CORS 功能。我做了一半,但我得到了我不期望的结果。
症状是我从端口号 1111 向我的服务发送了一条消息,但是我在服务器上启用了 CORS,我认为应该拒绝 1111 端口的配置,因为我有 2222 让我们在配置。我的服务器位于 3333 端口。
如果这有助于缩小范围,我正在使用 5.1.1 版本的 spring-web、spring-webmvc、spring-security-web、spring-security-config 和 spring-context。
这是非常简单的服务;
@RestController
public class MyService implements IMyService
IMyReqHandler requestHandler;
public MyService (IMyReqHandler requestHandler)
this.requestHandler = requestHandler;
@PostMapping("/dothings")
public void DoThings(@RequestBody MyMessageType msg)
requestHandler.processRequest(msg);
我目前的配置如下;
@EnableWebSecurity
public class CORSConfig extends WebSecurityConfigurerAdapter
@Override
protected void configure(HttpSecurity http) throws Exception
http.cors();
@Bean
CorsConfigurationSource corsConfigurationSource()
CorsConfiguration configuration = new CorsConfiguration();
configuration.setAllowedOrigins(Arrays.asList("http://localhost:2222"));
configuration.setAllowedMethods(Arrays.asList("POST"));
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/dothings", configuration);
return source;
我已经确认在启动过程中代码被命中。
确切的响应标头是;
HTTP/1.1 200
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: http://localhost:1111
Content-Length: 0
Date: Fri, 23 Nov 2018 12:48:06 GMT
由于我的配置,我预计响应标头中的 1111 为 2222。为什么不是这样?我错过了什么?
编辑:抱歉在这里误导,但事实证明我是通过另一段代码来获取这些标头的……在服务的方法上,我有注释;
@CrossOrigin(value = "http://localhost:1111")
这解释了 1111,但是当我删除该行时,我根本没有添加任何与 CORS 相关的标题。如果我从中删除值,我会得到 CORS 标头,但它们默认为“全部允许”,这不是我想要的。
我应该补充一点,当我删除有问题的代码行时,我看不到任何与 CORS 相关的标题。
为什么我的配置对我的服务调用没有任何影响?我需要一种动态设置值的方法...
【问题讨论】:
从副本中:我首先尝试了 Hendy 的答案,但没有用,我收到有关“NoSuchBeanDefinitionException:没有 'org.springframework.security.config.annotation.ObjectPostProcessor> 类型的合格 bean 的异常' 可用的”。如您所见,dur 的答案已经尝试过(请参阅 OP),而 AntonIva 的答案也不起作用,这与 OAuth 有关。这些答案都不起作用。已更新问题以反映这一点。 这个问题已经过重大修改。它变成了一篇关于失败的博客文章,所以我将其剥离到我的问题的本质。 【参考方案1】:我认为 CORS 控件存在。 CORS 控制是基于响应上的 Access-Control-Allow-Origin 标头和请求中发送的 Origin 标头完成的。如果它们都匹配,则允许调用该资源。
当您使用工具(不同于浏览器)调用资源时,通常不会添加 Origin 标头。或者添加与您的资源相同的域/IP 的 Origin 标头。
当请求来自服务器的同一域或请求来自不在您允许的来源 (setAllowedOrigins) 中的域时,Spring Security CORS 过滤器不会发送 Access-Control-Allow-Origin 标头。因为没有 Access-Control-Allow-Origin 标头,所以浏览器只允许来自同一域的请求。
如果您从允许的来源 (setAllowedOrigins) 上的域调用服务,则 Access-Control-Allow-Origin 将在响应中返回,并在 Origin 标头中显示域的名称。
测试
我使用相同的服务器和 2 个不同的端口(9797 和 9798)进行了测试
这是我的配置类
@Configuration
public class WebConfig implements WebMvcConfigurer
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**")
.allowedOrigins("http://localhost:9798")
.allowedMethods("POST", "GET")
.allowCredentials(true).maxAge(3600);
这些是响应标头
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: http://localhost:9798
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: application/json;charset=UTF-8
Date: Wed, 28 Nov 2018 14:07:08 GMT
Expires: 0
Pragma: no-cache
Transfer-Encoding: chunked
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
X-XSS-Protection: 1; mode=block
我从 localhost:9798 上的页面调用了 localhost:9797 中的服务,您可以看到标题 Access-Control-Allow-Origin: http://localhost:9798 存在。 (它们是 2 个请求,一个带有 OPTIONS,一个带有 POST)如果我从 http://localhost:9797 上的页面调用服务,则 Access-Control-Allow-Origin 标头不存在,但我可以调用服务没有问题。
【讨论】:
我正在使用 Chrome 来测试这个,所以它应该尊重 CORS 的东西。但是,当我收到来自服务器的响应时,它根本不包含有关 CORS 的信息,并且请求失败。 “当请求来自服务器的同一域时” 我对问题进行了轻微修改,希望能更清楚 @DanRayson 您认为这可能是因为地址仅因端口而异吗?是的,不同的端口意味着 CORS 中的不同服务器/域。我做了一个测试,但使用了 jsfiddle。我将使用同一服务器不同端口进行另一次测试 @DanRayson 我更改了答案示例,从配置中删除了 corsConfigurationSource bean,并添加了一个实现 addCorsMappings 方法的新类 WebConfig。此方法具有 cors 配置。 我上传了一个测试到 GitHub github.com/reos79/spring-cors 供你查看。以上是关于当我期望它时,CORS 的 Spring 实现不会拒绝消息的主要内容,如果未能解决你的问题,请参考以下文章
Vaadin Spring Projekt期望no-arg构造函数,只在tomcat上不是本地的
如何在 Spring Boot 中测试 CORS?当我在 MockMvcBuilders 中尝试时,尽管 Origin 错误,它总是返回 200
从 Firebase 托管到 Firebase 功能的请求被 CORS 阻止