通过 Cloudfront 请求 Spring 引导应用程序莫名其妙地失败,状态为 403
Request to Spring Boot application via Cloudfront fails inexplicably with 403 status
当我导航到 web.mysite.com
时,这是一个托管在 S3 中的静态 SPA,它有一个 iframe,它的 src
为 mysite.com/some/path
,这是一个 Spring 引导Elastic Beanstalk 中的 MVC 应用程序。两者都支持 HTTPS 的 Cloudfront 发行版。此路径在应用程序中使用自定义资源解析器进行处理。这加载成功,但在 iframe 内容中有一个脚本标记正在寻找 mysite.com/some/path/thatsdifferent
,由同一个解析器处理。
第二个请求失败并返回 403,我无法确定原因。直接在我的浏览器中导航到失败的 mysite.com/some/path/thatsdifferent
或使用 postman 成功,状态为 200。服务器配置为通过 CORS 配置允许来自 web.mysite.com
的请求(并且没有 CORS-related 错误消息)并且 Spring 安全配置为 permitAll
对 [=18] 的任何请求=] 无论身份验证如何。在 header x-cache: Error from cloudfront
之外没有响应 body 或错误消息。
如果我导航到 the-beanstalk-env-url.com/some/path
,它会加载 html,然后成功加载 the-beanstalk-env-url.com/some/path/thatsdifferent
中的内容。
对几个不同但相似路径的请求成功。去一条绝对 100% 不存在的路径 returns a 404.
服务器日志显示请求已成功处理,Cloudfront 正在向客户端返回合理的响应。查看 Cloudfront 日志仅报告 403,没有任何其他信息。
几乎 100% 的 Cloudfront 403 错误文章和问题都涉及 S3,这不是这里失败的部分。
将 Cloudfront 分发允许的方法从 GET, HEAD
更改为 GET, HEAD, OPTIONS
会导致直接向 mysite.com/some/path/thatsdifferent
的请求开始失败并显示 invalid CORS request
,已通过将 Accept, Authorization, Host, Origin
和 Referer
headers。这没有修复潜在的错误。
调整 org.springframework.security
的日志记录不会在发生失败请求时记录任何额外信息,我的应用程序安全配置不是导致错误的原因。
在我的 Route 53 环境中用负载均衡器替换 Cloudfront 后,场景按预期运行,所以问题肯定在 Cloudfront。
解决方案是将 Cloudfront Origin Protocol 策略从 HTTP Only
切换到 HTTPS Only
。
我不知道为什么这对脚本文件而不是 html 文件很重要,但是当我发现如果我尝试连接到 Beanstalk 环境 URL 通过 https,Chrome 警告我正在使用的证书是为导致问题的 Cloudfront 分发服务的域设置的。
当我导航到 web.mysite.com
时,这是一个托管在 S3 中的静态 SPA,它有一个 iframe,它的 src
为 mysite.com/some/path
,这是一个 Spring 引导Elastic Beanstalk 中的 MVC 应用程序。两者都支持 HTTPS 的 Cloudfront 发行版。此路径在应用程序中使用自定义资源解析器进行处理。这加载成功,但在 iframe 内容中有一个脚本标记正在寻找 mysite.com/some/path/thatsdifferent
,由同一个解析器处理。
第二个请求失败并返回 403,我无法确定原因。直接在我的浏览器中导航到失败的 mysite.com/some/path/thatsdifferent
或使用 postman 成功,状态为 200。服务器配置为通过 CORS 配置允许来自 web.mysite.com
的请求(并且没有 CORS-related 错误消息)并且 Spring 安全配置为 permitAll
对 [=18] 的任何请求=] 无论身份验证如何。在 header x-cache: Error from cloudfront
之外没有响应 body 或错误消息。
如果我导航到 the-beanstalk-env-url.com/some/path
,它会加载 html,然后成功加载 the-beanstalk-env-url.com/some/path/thatsdifferent
中的内容。
对几个不同但相似路径的请求成功。去一条绝对 100% 不存在的路径 returns a 404.
服务器日志显示请求已成功处理,Cloudfront 正在向客户端返回合理的响应。查看 Cloudfront 日志仅报告 403,没有任何其他信息。
几乎 100% 的 Cloudfront 403 错误文章和问题都涉及 S3,这不是这里失败的部分。
将 Cloudfront 分发允许的方法从 GET, HEAD
更改为 GET, HEAD, OPTIONS
会导致直接向 mysite.com/some/path/thatsdifferent
的请求开始失败并显示 invalid CORS request
,已通过将 Accept, Authorization, Host, Origin
和 Referer
headers。这没有修复潜在的错误。
调整 org.springframework.security
的日志记录不会在发生失败请求时记录任何额外信息,我的应用程序安全配置不是导致错误的原因。
在我的 Route 53 环境中用负载均衡器替换 Cloudfront 后,场景按预期运行,所以问题肯定在 Cloudfront。
解决方案是将 Cloudfront Origin Protocol 策略从 HTTP Only
切换到 HTTPS Only
。
我不知道为什么这对脚本文件而不是 html 文件很重要,但是当我发现如果我尝试连接到 Beanstalk 环境 URL 通过 https,Chrome 警告我正在使用的证书是为导致问题的 Cloudfront 分发服务的域设置的。