公共桶的S3 CORS策略
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了公共桶的S3 CORS策略相关的知识,希望对你有一定的参考价值。
这似乎很容易,但我不知道我错过了什么。我有一个带有js脚本的公共存储桶,我从我的网站上获取。我注意到我没有向S3发送Origin
标头,它不是必需的,一切都可以在没有任何CORS配置的情况下运行。
更重要的是,即使我手动将Origin标头添加到该GET调用并通过以下方式明确禁止GET和我的域:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://www.nonexistingdomain.com</AllowedOrigin>
<AllowedMethod>POST</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
我仍然可以获得内容。这里发生了什么?
同源策略是浏览器强制执行的功能,可防止在一个网站上运行的javascript从其他网站读取数据。 (这会阻止使用JavaScript的随机网站使用您的浏览器跳过您的公司防火墙并访问您的内部网或使用您的cookie读取您的GMail)。
CORS让网站放宽同源策略,允许其他网站以这种方式从中读取数据。
CORS不是身份验证/授权。您的公共存储桶是公开的。
您没有使用JavaScript从存储桶中读取数据,而是直接从存储桶中加载JS。
好吧,在与Quentin交谈后,我想我明白我在哪里误解了CORS应该如何工作。在Java世界中,当Origin不匹配时,实际拒绝请求是一种非常常见的做法。这是另一个线程,它是mentioned。如果我们以Spring为例(这是Java世界中事实上的标准),那么添加CORS过滤器时会发生以下情况:
String allowOrigin = checkOrigin(config, requestOrigin);
...
if (allowOrigin == null) {
logger.debug("Reject: '" + requestOrigin + "' origin is not allowed");
rejectRequest(response);
return false;
}
哪里:
/**
* Invoked when one of the CORS checks failed.
*/
protected void rejectRequest(ServerHttpResponse response) {
response.setStatusCode(HttpStatus.FORBIDDEN);
}
你可以找到代码here。
但令我惊讶的是,对于其他堆栈和服务器端技术来说,这并不常见。另一种常见的方法是将他们拥有的任何CORS配置发送到浏览器并将决定权交给它。
S3更加棘手:当桶CORS规则与启用CORS的请求(请求qith Origin头)匹配时,它仅发送CORS响应头。否则,将没有CORS响应头。
让我们分解问题并尝试理解CORS的基本原理。
What is Cross-Origin Request & CORS?
跨源请求:对源外的资源(如图像或字体)的请求称为跨源请求。
当您从其他来源请求受保护资源时,CORS很有用。
跨源请求共享:对源外的受保护资源(如图像或字体或XHR请求)的请求称为跨源请求。
Why do we need CORS when the resources can be protected by using authentication/authorization tokens?
CORS是第一道防线。当客户端(例如,浏览器)和服务器都是CORS感知的时,客户端将仅允许根据服务器的指示从特定源到服务器的请求。
默认情况下,浏览器应根据构建浏览器的指导原则实现同源策略安全机制。几乎所有现代浏览器都实现同源策略,指示浏览器在源相同时允许对服务器的请求。
同源策略是浏览器的安全机制,您可以阅读更多关于它的here。正是由于浏览器的这一特性,当指定源和源原点不同时,浏览器会阻止所有请求。 (服务器甚至不知道发生了这种情况,哇!)
对于更简单的用例,当资产(js,CSS,图像,字体),XHR资源可以使用相同的原点访问时,无需担心CORS。
如果资产托管在另一个源上,或者XHR资源托管在具有不同域的服务器上,则源默认情况下浏览器不会拒绝跨源请求。只有使用适当的CORS请求和响应头,才允许浏览器发出跨域请求。
我们来看看请求和响应标头。
- 起源
- 访问控制请求法
- 访问控制请求报头
- 访问控制允许来源
- 访问控制允许的凭据
- 访问控制展露报头
- 访问控制 - 最大 - 年龄
- 访问控制允许方法访问控制允许标头
要设置CORS,需要使用Origin
和Access-Control-Allow-Origin
标头。浏览器会自动为每个请求添加Origin
标头,因此开发人员只需要配置Access-Control-Allow-Origin
响应标头。
为了保护仅从特定域访问资源,S3提供了配置CORS规则的选项。如果Access-Control-Allow-Origin
头的值是*
,则允许所有跨源请求,或者定义以逗号分隔的域列表。
使用CORS时需要注意几点。
- 这是受保护资源的第一级防御,而不是最终的防御。
- 您仍需要对资源实施适当的身份验证和授权,以便在服务器上执行CRUD操作。
- 实施同源策略是构建浏览器的指南,不是强制性的。
- 仅当客户端接受标头时,CORS标头才有用。只有现代浏览器接受CORS标头。如果您不使用浏览器发出资源请求,则CROS不适用。
- 如果在浏览器的地址栏中键入链接,则不应用CORS规则,因为浏览器不会将
Origin
标头发送到服务器。Origin
标头仅由后续资源请求(样式表,js文件,字体)和源的XHR请求由浏览器发送。 如果通过直接在地址栏中键入链接来访问资源文件,则浏览器不会向该请求发送Origin
标头。
此外,如果要限制GET访问,请在专用存储桶上使用S3预签名URL。
以上是关于公共桶的S3 CORS策略的主要内容,如果未能解决你的问题,请参考以下文章
被 CORS 策略阻止 - 来自 Django 应用程序的 S3 存储桶访问
没有 S3 存储桶的 AWS Cloudfront CORS 标头
如何在使用 javascript fetch 函数时设置公共 Google Cloud Storage 存储桶的 CORS 以避免错误?