Spring Boot + Security:设置允许的来源时没有 Access-Control-Allow-Origin 标头

Posted

技术标签:

【中文标题】Spring Boot + Security:设置允许的来源时没有 Access-Control-Allow-Origin 标头【英文标题】:Spring Boot + Security: No Access-Control-Allow-Origin header when setting allowed origins 【发布时间】:2019-06-14 01:50:36 【问题描述】:

我将 Spring Boot v2.1.1.RELEASE 与 Spring Security 一起使用,并尝试通过 REST 登录应用程序。

我有一个实现 WebMvcConfigurer 的配置文件,所以我可以覆盖 addCorsMappings 方法:

@Override
public void addCorsMappings(final CorsRegistry registry) 
    registry.addMapping("/**");

这很好用;我可以将我的登录数据发送到http://localhost:8080/login 并获得正常的响应,包括会话 cookie 和所有内容:

Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 0
Date: Sun, 20 Jan 2019 13:14:46 GMT
Expires: 0
Pragma: no-cache
Set-Cookie: JSESSIONID=66B74AE4F547BA77604AE199E0A48D7E; Path=/; HttpOnly
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

注意Access-Control-Allow-Origin 标头。 但是,如果我按如下方式指定允许的来源,则响应不包含前面提到的标头:

@Override
public void addCorsMappings(final CorsRegistry registry) 
    registry.addMapping("/**").allowedOrigins("localhost");

将导致响应:

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Length: 20
Date: Sun, 20 Jan 2019 13:15:15 GMT
Expires: 0
Pragma: no-cache
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

我允许哪个来源无关紧要; “http://localhost”、“http://example.com”和“example.com”都导致相同的结果。

在调试时,我注意到当我在代码中包含allowedOrigins 位时,身份验证过程在 CorsFilter 处停止。

这就是登录过程!我不能使用@CrossOrigin 注释(据我所知),因为我没有办法把它放在上面。

我正在使用此脚本测试 REST 登录:https://pastebin.com/YezC3wWr

这是 Spring 中的错误还是设计使然?我在这里遗漏了什么吗?

编辑:响应中的“Access-Control-Allow-Origin”标头仅在请求从允许的来源发送时才会发送,但事实并非如此。我在http://localhost:8000 上托管了html 测试文件,所以我必须将这个确切的URL 添加到服务器上允许的来源。不是localhost,不是localhost:8000,而是http://localhost:8000。然后身份验证成功,并且标头也包含在响应中。

【问题讨论】:

【参考方案1】:

如果您在与登录请求相同的域中运行 HTML 页面,则请求中将没有 Origin 标头,因此没有 Access-Control-Allow-Origin。 您的代码是这种情况吗?你在http://localhost:8080/下运行HTML文件吗?

如果不是,请从浏览器的控制台发布错误。 另外,如果您可以同时发布请求和响应标头,那就太好了

【讨论】:

【参考方案2】:

尝试使用“http://localhost:8080”。 您是通过网络浏览器测试它还是直接使用 Postman 进行 POST 测试?

【讨论】:

那个网址也不起作用。我正在通过 Web 浏览器使用以下 HTML 文件对其进行测试:pastebin.com/YezC3wWr 用完你的 html 文件后,打开浏览器控制台并导航到网络部分。然后重新加载页面并尝试登录。 OPTIONS 请求是否通过? 它不执行任何 OPTIONS 请求(这很奇怪吗?),无论是否有允许的来源。对http://localhost:8080/login只有一个POST请求。 尝试将 xhr.setRequestHeader("Origin", "localhost:8080") 添加到您的 html 文件中。另外请使用 Postman 检查 POST 登录调用的结果。 发现了问题,我将 HTML 文件托管在 http://localhost:8000,而不是 8080。当我将它添加到允许的来源时,一切都很好。

以上是关于Spring Boot + Security:设置允许的来源时没有 Access-Control-Allow-Origin 标头的主要内容,如果未能解决你的问题,请参考以下文章

spring boot 整合security 4 怎么设置忽略的静态资源

spring boot整合security 4,怎么设置忽略的静态资源?

Spring Boot + Security:设置允许的来源时没有 Access-Control-Allow-Origin 标头

使用 Spring Security 进行 Spring Boot 单元测试

微服务:整合 Spring Boot Admin - 开启Security安全认证

Spring Boot + Spring Security + Spring OAuth2 + Google 登录