不跨站点共享ASP.NET5,MVC 6 Cookie

时间:2016-03-30 05:09:30

标签: c# asp.net-mvc cookies

我有一个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

我做错了什么?

编辑:其他信息 我主要是从Chrome测试,但似乎与IE11相同。 我可以在Chrome中看到Cookie。 Cookies from Chrome

3 个答案:

答案 0 :(得分:3)

TL; DR

由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主机名完全不匹配,则应忽略作为公共后缀的域。 (遵循此规则取决于客户端选择和配置,但浏览器通常遵循该规则。)

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.
Mozilla处理的

Public suffix list会列出azurewebsites.net

  

// Microsoft:http://microsoft.com
  //由Barry Dorrans提交   azurewebsites.net
  azure-mobile.net
  cloudapp.net

所以,这是非常逻辑的,微软已经积极禁止从子域azurewebsites.net设置的cookie。

解决OP findings and own answer

由于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 不能为“*”。

HTTP access control (CORS)

答案 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设置为安全问题。