Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
547 views
in Technique[技术] by (71.8m points)

c# - ASP.NET5, MVC 6 Cookies not being shared across sites

I have an ASP.NET5/MVC6 website and a corresponding OData Service both hosted on azure.

As an experiment I am attempting to set a cookie on the website (xxxportal.azurewebsites.net) and access the cookie in the OData Service (xxxservice.azurewebsites.net).

I am setting the cookie in the AccountController with the following code.

  Response
    .Cookies
    .Append(
        "MyCookie", 
        "MyCookieValue", 
         new Microsoft.AspNet.Http.CookieOptions 
         { 
              Domain = "azurewebsites.net", 
              Path="/", 
              HttpOnly = true, 
              Expires = DateTime.MaxValue 
          });

When I run Fiddler I can see that the cookie is set.

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

But on the request to the ODataService the cookie is not being sent. (I also don't see it sent on the subsequent requests to the same site.)

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

What am I doing wrong?

EDIT: Additional Information I'm mostly testing from Chrome but seems to be the same from IE11. I can see the cookies in Chrome. Cookies from Chrome

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

#TL;DR

As founded by OP and answered here, he is falling in another case than the ones myi nitial answer was addressing. His case implies CORS, and probably a preflight request. Then his case can be handled by adding the Access-Control-Allow-Credentials in the resource preflight response and in the Set-Cookieresponse too. It seems to overrides the Cookie rules I explain below.

Here is my old answer, still true but not explaining the whole thing:

Microsoft has banned cookies on azurewebsites.net top domain by including it in public suffix list.

#Full details According to RFC 6265, setting a cookie for your site top domain is supported:

The user agent will reject cookies unless the Domain attribute specifies a scope for the cookie that would include the origin server. For example, the user agent will accept a cookie with a Domain attribute of "example.com" or of "foo.example.com" from foo.example.com, but the user agent will not accept a cookie with a Domain attribute of "bar.example.com" or of "baz.foo.example.com".

So, if your set-cookie on domain yourdomain.net occurs from a request on a yourdomain.net sub-domain, this cookie should be accepted.

And as written a bit above:

The Domain attribute specifies those hosts to which the cookie will be sent. For example, if the value of the Domain attribute is "example.com", the user agent will include the cookie in the Cookie header when making HTTP requests to example.com, www.example.com, and www.corp.example.com.

So your accepted cookie should be sent to any subdomain of yourdomain.net on subsequent requests.

But as per §5.3, point 5, a domain being a public suffix should be ignored if the http hostname does not match it entirely. (Following this rule depends on client choices and configuration, but browsers usually follow that rule.)

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 handled by Mozilla does list azurewebsites.net.

// Microsoft : http://microsoft.com
// Submitted by Barry Dorrans
azurewebsites.net
azure-mobile.net
cloudapp.net

So, and that is quite logic, Microsoft has actively banned cookies set on azurewebsites.net from sub domains.

Addressing OP findings and own answer:

Due to azurewebsites.net being in public prefix list, Set-Cookie on azurewebsites.net from a azurewebsites.net sub-domain should be ignored.

But if the response setting the cookie include additional CORS headers (Access-Control-Allow-Credentials along with more classical ones) allowing explicitly credential sharing, the CORS header seems to take precedence and causes the browser to accept the cookie even on public suffix.

I was unfortunately unable to find any spec about that behavior. If "CORS header allowing something forbidden by cookie rules" is actually an unspecified case, this may change, and it is then risky to rely on this.

If any preflight occurs on the request needing to transmit the shared cookie, then the preflight response will very probably have to include the Access-Control-Allow-Credentials header too.

#Additional consideration

CORS spec recommends avoiding browser based automatic credentials forwarding mechanisms.

Given the difficulty of avoiding such vulnerabilities in multi-origin interactions it is recommended that, instead of using user credentials automatically attached to the request by the user agent, security tokens which specify the particular capabilities and resources authorized be passed as part of the explicit content of a request. OAuth again provides an example of such a pattern.

It would probably be more robust to follow this recommendation.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...