我有一个ASP.NET5 / MVC6网站和相应的OData服务都托管在azure上。
作为一项实验,我试图在网站上设置一个cookie(xxxportal.azurewebsites.net)并访问OData服务中的cookie(xxxservice.azurewebsites.net)。
我使用以下代码在AccountController中设置cookie。
Response
.Cookies
.Append(
"MyCookie",
"MyCookieValue",
new Microsoft.AspNet.Http.CookieOptions
{
Domain = "azurewebsites.net",
Path="/",
HttpOnly = true,
Expires = DateTime.MaxValue
});
当我运行Fiddler时,我可以看到cookie被设置了。
HTTP/1.1 302 Found
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 0
Expires: -1
Location: /
Server: Microsoft-IIS/8.0
Set-Cookie: .AspNet.Microsoft.AspNet.Identity.Application=CfDJ8B0ErUB73iFHtoSI2Xl7xKIM6bTPDudGXYwJ--ia_gE416t-asXaZS2_hg8C4OF1NqMLy39hehNKwRvJKpuYP44h_Cb5sLN3fMV2iVoIkHa7O9JNPXVI8EmZXhx3xQNUNnSo5zMWoIuZjXUJG4WoWYUFqPmUVbjaaAQgT6nCxSPi34kwBBLRXQbHwZxGVJgpTDDHFKSthzYCk8wYcBwh-Izjc7zja8mXuEtVDXyBWGWtFFkJSae2DltVWShWfPG7Z_jtD7909aLh0eGzpZQY7pDxftYgfoLZPwnbDZVvrx65RGhFk6A8N3jv3CMdIJDtxjO8m367fnsNJzve2IDn7npDf1OOvFCM9MIWfZ67Ns8w4vV3eIgGO6kAs_gop3mDphFH8ZRW8RwKhBiHhOoA76IVzgkeZWvZXvQeJDbUvTGfyMjgHQVnzWQJnvg5Gvz6JGNrpM8Yv7JxYrXVFrbtM6k7Aw83Cf9_JQAYBCSz6URYCKX3O_FApNCrhGsNtp4RkMdBa-uFnuQZ4ZgnRMMGuavMJLQ7zLz_KzPjBS3H3iyaYUaWVvXx5QgWWwHoWlIV0Yb_Ba_hxCVmoOSMQMXkkqSTHOxs2WZC5EcRF7zJprUVxR3FAR8c4_AhG3r9t5hAtwEE5l6T2oxOhgqe7Xkn1rY; path=/; httponly
Set-Cookie: MyCookie=MyCookieValue; expires=Fri, 31 Dec 9999 23:59:59 GMT; domain=azurewebsites.net; path=/; httponly
X-Powered-By: ASP.NET
Date: Wed, 30 Mar 2016 04:34:48 GMT
但是在对ODataService的请求中,没有发送cookie。 (我也没有看到它随后发送到同一网站的请求。)
GET http://xxxservice.azurewebsites.net/Patients HTTP/1.1
Host: xxxservice.azurewebsites.net
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
Accept: application/json, text/plain, */*
Origin: http://xxxportal.azurewebsites.net
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36
Referer: http://xxxportal.azurewebsites.net/
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
我做错了什么?
答案 0 :(得分:3)
由OP创立并回答here,他正处于另一个案件中,而不是myi nitial回答所解决的案件。他的案子意味着CORS,可能还有飞行前请求。然后,可以通过在资源预检响应和Access-Control-Allow-Credentials
响应中添加Set-Cookie
来处理他的案例。它似乎取代了我在下面解释的Cookie
规则。
这是我的老答案,仍然是正确但不解释整个事情:
Microsoft已在azurewebsites.net
顶级域名中禁止使用Cookie,方法是将其包含在public suffix list中。
根据RFC 6265,支持为您的网站顶级域设置Cookie:
除非Domain属性指定包含原始服务器的cookie的范围,否则用户代理将拒绝cookie。例如,用户代理将接受来自foo.example.com的域属性为“example.com”或“foo.example.com”的cookie,但用户代理不接受域属性为“bar.example.com”或“baz.foo.example.com”。
因此,如果域yourdomain.net
上的set-cookie来自yourdomain.net
子域上的请求,则应接受此Cookie。
如上所述:
Domain属性指定将向其发送cookie的主机。例如,如果Domain属性的值为“example.com”,则在向example.com,www.example.com和www.corp.example发出HTTP请求时,用户代理将在Cookie标头中包含cookie。融为一体
因此,您接受的Cookie应在后续请求中发送到yourdomain.net
的任何子域。
但是根据§5.3, point 5,如果http主机名完全不匹配,则应忽略作为公共后缀的域。 (遵循此规则取决于客户端选择和配置,但浏览器通常遵循该规则。)
Mozilla处理的5. If the user agent is configured to reject "public suffixes" and the domain-attribute is a public suffix: If the domain-attribute is identical to the canonicalized request-host: Let the domain-attribute be the empty string. Otherwise: Ignore the cookie entirely and abort these steps.
Public suffix list会列出azurewebsites.net
。
// Microsoft:http://microsoft.com
//由Barry Dorrans提交 azurewebsites.net
azure-mobile.net
cloudapp.net
所以,这是非常逻辑的,微软已经积极禁止从子域azurewebsites.net
设置的cookie。
由于azurewebsites.net
位于公共前缀列表中,因此应忽略来自azurewebsites.net
子域的azurewebsites.net
上的Set-Cookie。
但是如果设置cookie的响应包括额外的CORS头(Access-Control-Allow-Credentials
以及更经典的头)允许明确的凭据共享,CORS头似乎优先并导致浏览器甚至在公共后缀上接受cookie
遗憾的是,我无法找到有关该行为的任何规范。如果“CORS标题允许cookie规则禁止某些内容”实际上是一个未指定的情况,这可能会发生变化,那么依赖它就有风险。
如果在需要传输共享cookie的请求上发生任何预检,那么预检响应很可能也必须包含Access-Control-Allow-Credentials
标题。
CORS spec建议避免使用基于浏览器的自动凭据转发机制。
鉴于在多源交互中难以避免此类漏洞,建议不要使用由用户代理自动附加到请求的用户凭据,而是指定授权的特定功能和资源的安全令牌作为请求的显式内容。 OAuth再次提供了这种模式的一个例子。
遵循此建议可能会更加健壮。
答案 1 :(得分:1)
最初认为@Frédéric有正确答案,但我无法使用专用服务器。
最后我发现了这篇文章Cross domain JQuery ajax call with credentials。 @Emily接受的答案指出服务器必须发送以下标题。
Access-Control-Allow-Origin: http://www.mywebsite.com
Access-Control-Allow-Credentials: true
另一个重要的部分是,如果您包含Allow-Credentials标头,则Allow-Origin 不能为“*”。
答案 2 :(得分:0)
然而,我无法在设置的Cookie标头标签上找到实际的doco。
Domain和Path属性定义cookie的范围。 他们基本上告诉浏览器cookie属于哪个网站。 出于明显的安全原因,cookie只能在当前资源的顶级域及其子域上设置,而不能在其他域及其子域上设置。 例如,网站example.org无法设置具有foo.com域名的cookie,因为这将允许example.org网站控制foo.com的cookie。
以上是维基百科的摘录。 - > https://en.wikipedia.org/wiki/HTTP_cookie
我认为抢劫是正确的,因为你不能将来自其他域的cookie设置为安全问题。