访问控制如何允许源标题工作?

bxgwgixi  于 2021-09-23  发布在  Java
关注(0)|答案(4)|浏览(341)

显然,我完全误解了它的语义。我想到了这样的事情:
客户端从下载javascript代码mycode.js http://siteA -起源。
mycode.js的响应头包含访问控制允许来源: http://siteB ,我认为这意味着mycode.js可以对站点b进行跨源引用。
客户端触发mycode.js的一些功能,这些功能反过来向 http://siteB ,这应该没问题,尽管是跨来源请求。
嗯,我错了。它根本不是这样工作的。所以,我已经阅读了跨源资源共享,并尝试阅读w3c推荐中的跨源资源共享
有一件事是肯定的-我仍然不明白我应该如何使用这个标题。
我完全控制了现场a和现场b。如何使从站点a下载的javascript代码能够使用此标头访问站点b上的资源?
附笔
我不想使用jsonp。

bis0qfac

bis0qfac1#

每当我开始考虑cors时,我对哪个站点承载标题的直觉是不正确的,正如您在问题中所描述的那样。对我来说,思考同一原产地政策的目的是有帮助的。
同源策略的目的是防止sitea.com上的恶意javascript访问您选择仅与siteb.com共享的私人信息。如果没有同源策略,sitea.com作者编写的javascript可能会使浏览器使用siteb.com的身份验证cookie向siteb.com发出请求。这样,sitea.com就可以窃取您与siteb.com共享的机密信息。
有时,您需要跨域工作,这就是cors的作用。cors使用 Access-Control-Allow-Origin 标题列出其他域(domaina.com),这些域被信任可以运行可以与domaina.com交互的javascript。
要理解哪个域应该为CORS头服务,请考虑这一点。您可以访问恶意网站mybank.com,它包含一些javascript,试图向mybank.com发出跨域请求。应该由mybank.com而不是恶意网站来决定是否设置cors头来放松同源策略,允许恶意网站的javascript与之交互。如果malicous.com可以设置自己的cors头,允许自己的javascript访问mybank.com,这将完全取消同源策略。
我认为我直觉不好的原因是我在开发网站时的观点。这是我的网站,有我所有的javascript,因此它没有做任何恶意的事情,它应该是u

jm2pwxwz

jm2pwxwz2#

Access-Control-Allow-Origin 是cors(跨源资源共享)标头。
当站点a尝试从站点b获取内容时,站点b可以发送 Access-Control-Allow-Origin 响应标题,告知浏览器某些来源可以访问此页面的内容(原点是一个域,加上一个方案和端口号。)默认情况下,任何其他原点都无法访问站点b的页面;使用 Access-Control-Allow-Origin header为特定请求来源的跨来源访问打开一扇门。
对于站点b希望站点a访问的每个资源/页面,站点b应为其页面提供响应标题:

Access-Control-Allow-Origin: http://siteA.com

现代浏览器不会完全阻止跨域请求。如果站点a从站点b请求页面,浏览器将实际在网络级别获取请求的页面,并检查响应头是否将站点a列为允许的请求者域。如果站点b未指示允许站点a访问此页面,浏览器将触发 XMLHttpRequesterror 事件并拒绝请求javascript代码的响应数据。

非简单请求

在网络层面上发生的事情可能比上面解释的稍微复杂一些。如果请求是“非简单”请求,浏览器首先发送一个无数据的“飞行前”选项请求,以验证服务器是否会接受该请求。在以下情况下,请求是非简单的:
使用非get或post的http动词(例如put、delete)
使用非简单请求头;唯一的简单请求标头是:
Accept Accept-Language Content-Language Content-Type (只有当其值为 application/x-www-form-urlencoded , multipart/form-datatext/plain )
如果服务器使用适当的响应头响应飞行前选项( Access-Control-Allow-Headers 对于非简单标题, Access-Control-Allow-Methods 对于与非简单动词和/或非简单标题匹配的非简单动词),浏览器将发送实际请求。
假设站点a想要发送一个put请求 /somePage ,带有一个非简单的 Content-Type 价值 application/json ,浏览器将首先发送飞行前请求:

OPTIONS /somePage HTTP/1.1
Origin: http://siteA.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type

注意 Access-Control-Request-MethodAccess-Control-Request-Headers 由浏览器自动添加;您不需要添加它们。此选项预飞行获取成功响应标题:

Access-Control-Allow-Origin: http://siteA.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type

发送实际请求时(飞行前完成后),行为与处理简单请求的方式相同。换句话说,预飞成功的非简单请求被视为与简单请求相同(即,服务器仍必须发送 Access-Control-Allow-Origin 再次说明实际响应)。
浏览器发送实际请求:

PUT /somePage HTTP/1.1
Origin: http://siteA.com
Content-Type: application/json

{ "myRequestContent": "JSON is so great" }

然后服务器返回一个 Access-Control-Allow-Origin ,就像一个简单的请求:

Access-Control-Allow-Origin: http://siteA.com

有关非简单请求的更多信息,请参阅了解cors上的xmlhttprequest。

qcuzuvrc

qcuzuvrc3#

跨来源资源共享- CORS (又称跨域ajax请求)是大多数web开发人员可能遇到的问题,根据同源策略,浏览器在安全沙箱中限制客户端javascript,通常js无法直接与来自不同域的远程服务器通信。过去,开发人员创建了许多复杂的方法来实现跨域资源请求,最常用的方法是:
使用flash/silverlight或服务器端作为“代理”与远程服务器通信。
带填充的json(jsonp)。
将远程服务器嵌入iframe中,并通过fragment或window.name进行通信,请参阅此处。
这些棘手的方法或多或少都有一些问题,例如,如果开发人员简单地“评估”jsonp,jsonp可能会导致安全漏洞,以及上面的第3条,尽管它可以工作,但两个域应该在彼此之间建立严格的契约,这既不灵活也不优雅(imho:)
w3c引入了跨源资源共享(cors)作为标准解决方案,以提供安全、灵活和推荐的标准方法来解决此问题。
机制
从较高的层次上,我们可以简单地认为cors是来自域a的客户端ajax调用与域b上托管的页面之间的契约,典型的跨源请求/响应是:
域ajax请求头

Host DomainB.com
User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64; rv:2.0) Gecko/20100101 Firefox/4.0
Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8,application/json
Accept-Language en-us;
Accept-Encoding gzip, deflate
Keep-Alive 115
Origin http://DomainA.com

域B响应头

Cache-Control private
Content-Type application/json; charset=utf-8
Access-Control-Allow-Origin DomainA.com
Content-Length 87
Proxy-Connection Keep-Alive
Connection Keep-Alive

我上面标记的蓝色部分是核心事实,“来源”请求头“表示跨来源请求或飞行前请求的来源”,“访问控制允许来源”响应头表示此页面允许来自domaina的远程请求(如果值为*表示允许来自任何域的远程请求)。
正如我前面提到的,w3建议浏览器在提交实际的跨源http请求之前实现一个“飞行前请求”,简而言之,它是一个http请求 OPTIONS 请求:

OPTIONS DomainB.com/foo.aspx HTTP/1.1

如果foo.aspx支持选项http predicate ,它可能会返回如下响应:

HTTP/1.1 200 OK
Date: Wed, 01 Mar 2011 15:38:19 GMT
Access-Control-Allow-Origin: http://DomainA.com
Access-Control-Allow-Methods: POST, GET, OPTIONS, HEAD
Access-Control-Allow-Headers: X-Requested-With
Access-Control-Max-Age: 1728000
Connection: Keep-Alive
Content-Type: application/json

只有当响应包含“access control allow origin”且其值为“*”或包含提交cors请求的域时,通过满足此强制条件,浏览器才会提交实际的跨域请求,并将结果缓存在“飞行前结果缓存”中。
三年前我写了一篇关于cors的博客:ajax跨源http请求

z4bn682m

z4bn682m4#

这个问题有点太老了,无法回答,但我发布这个帖子是为了将来参考这个问题。
根据mozilla开发者网络的这篇文章,
当资源从与第一个资源本身所服务的域或端口不同的域或端口请求资源时,它会发出跨源http请求。

从中提供的html页面 http://domain-a.com 制造 <img> src请求 http://domain-b.com/image.jpg .
如今,web上的许多页面都从不同的域加载css样式表、图像和脚本等资源(因此应该很酷)。

同一原产地政策

出于安全原因,浏览器限制从脚本中启动的跨源http请求。
例如 XMLHttpRequestFetch 遵循同一原产地政策。
因此,使用 XMLHttpRequestFetch 只能向其自己的域发出http请求。

跨来源资源共享(cors)

为了改进web应用程序,开发人员要求浏览器供应商允许跨域请求。
跨源资源共享(cors)机制为web服务器提供跨域访问控制,从而实现安全的跨域数据传输。
现代浏览器在api容器中使用cors,例如 XMLHttpRequestFetch -以降低跨源http请求的风险。

cors的工作原理(访问控制允许源标题)

维基百科:
cors标准描述了新的http头文件,这些头文件为浏览器和服务器提供了一种仅当它们拥有权限时才请求远程URL的方法。
虽然服务器可以执行一些验证和授权,但浏览器通常有责任支持这些头并遵守它们施加的限制。

范例

浏览器发送 OPTIONS 请求 Origin HTTP 标题。
此标头的值是为父页提供服务的域。当一页从 http://www.example.com 尝试在中访问用户的数据 service.example.com ,将向发送以下请求标头 service.example.com :
来源:http://www.example.com
服务器位于 service.example.com 可答复如下:
Access-Control-Allow-Origin (acao)在其响应中的标题,指示允许哪些源站点。
例如: Access-Control-Allow-Origin: http://www.example.com 如果服务器不允许跨源请求,则显示错误页
Access-Control-Allow-Origin (acao)带有通配符的标头,允许所有域: Access-Control-Allow-Origin: *

相关问题