域未用于子域的Cookie [英] Cookie for domain not being used for subdomains

查看:95
本文介绍了域未用于子域的Cookie的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的应用程序中使用HttpClient将我的用户/密码发送到一个服务,该服务返回一些我以后可以用于其他所有请求的cookie。该服务位于`https:// accounts.dev.example.com / login`,并返回两个具有`Domain = .dev.example.com`的cookie。
我发现的问题是,在某些机器(Windows域控制器)中,当我在子域名中请求资源时,这些cookie没有被使用,例如`https://accounts.dev.example.com/health- check`,但根据MDN文档,域
的cookie可用于向子域请求资源:

 

* Domain =< domain-value> ;可选*

指定将向其发送cookie的主机。如果未指定,则默认为当前文档位置的主机部分(但不包括子域)。与早期的规范相反,域名中的前导点被忽略。 **如果指定了域名,则子域名始终包括在内。**




您知道如何正确配置` HttpClient`将域cookie传递给子域请求?



更多细节:



我的身份验证服务在https:// accounts.dev.example.com / login`返回的cookie在HTTP标头中如下所示:

 Set -Cookie:AK = 112233; Version = 1; Domain = .dev.example.com; Path = /; Max-Age = 5400; Secure; HttpOnly,  
Set-Cookie:AS = 445566; Version = 1; Domain = .dev.example.com; Path = /; Max-Age = 5400; Secure; HttpOnly, 


然后我可以查询的C#`CookieContainer`与任一这些调用在正常工作站:
<预类= "prettyprint"> cookies.GetCookies(QUOT; HTTPS://accounts.dev.example.com")
cookies.GetCookies(" https://dev.example.com")


这两个将返回2个Cookie,如:

 $版= 1; AK = 112233; $ PATH = /; $ Domain = .dev.example.com 
$ Version = 1; AS = 445566; $ PATH = /; $ Domain = .dev.example.com


但是在其他机器(域控制器)中,第一个调用将返回一个空列表,而第二个调用将返回2个cookie。 />


为什么CookieContainer.GetCookies的行为存在差异,具体取决于运行代码的机器?



我的工作站使用的是"Microsoft Windows 10 Home Single Language(.Net 4.0.30319.42000)",DC正在使用`Microsoft Windows Server 2012 R2 Datacenter(.Net 4.0.30319.36399)`。$


临时解决方案



这是我到目前为止的解决方案,有效,但不确定是否有正确的方法解决问题:

  &NBSP; foreach(Cookie中的Cookie Cookie.GetCookies(新的Uri(" https://dev.example.com")))
  &NBSP; {
  &NBSP; &NBSP; &NBSP; cookies.Add(new Uri(" https://accounts.dev.example.com"),new Cookie(cookie.Name,cookie.Value,cookie.Path," .accounts.dev.example.com") );
  &NBSP; }


所以,我正在复制我的应用程序应将这些cookie发送到的每个子域的cookie,



代码

$
这是我的代码的修改版本:

  public static async Task< string> DoAuth(的CookieContainer饼干,
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ;&NBSP;字典<串,串> postHeaders,
&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP ;     StringContent postBody)
  &NBSP; {
  &NBSP; &NBSP; &NBSP;试试
  &NBSP; &NBSP; &NBSP; {
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;使用(var handler = new HttpClientHandler())
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; handler.CookieContainer = cookies;
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;使用(var client = new HttpClient(handler,true))
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; {
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; foreach(postHeaders.Keys中的var键)
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; client.DefaultRequestHeaders.Add(key,postHeaders [key]);

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; var response = await client.PostAsync(" https://accounts.dev.example.com/login",postBody);
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; response.EnsureSuccessStatusCode();
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;&NBSP;
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; //此行在域控制器中返回0,在所有其他计算机中返回2
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; Console.Write(cookies.GetCookies(QUOT; HTTPS://accounts.dev.example.com").Count之间);

  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; return await response.Content.ReadAsStringAsync();
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; }
  &NBSP; &NBSP; &NBSP; }
  &NBSP; &NBSP; &NBSP; catch(HttpRequestException e)
  &NBSP; &NBSP; &NBSP; {
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP; ...
  &NBSP; &NBSP; &NBSP; &NBSP; &NBSP;扔;
  &NBSP; &NBSP; &NBSP; }
  &NBSP; }





原始问题:




解决方案

您好MondKin,


谢谢你可以在这里发帖。


请尝试以下方法设置子域名。

 Response.Cookies ["domain"] .value的= DateTime.Now.ToString(); 
Response.Cookies ["结构域"] .Expires = DateTime.Now.AddDays(1);
Response.Cookies ["结构域"]。域= "support.contoso.com";

support.contoso.com是www.contoso.com的子域名。


有关详细信息,请参阅MSDN文档。


https://msdn.microsoft.com/en-us/library/ms178194.aspx


最好的问候,


温迪


I use HttpClient in my app to send my user/password to a service that returns some cookies that I can later use for all my other requests. The service is located at `https://accounts.dev.example.com/login` and returns two cookies that have `Domain=.dev.example.com`. The issue I'm finding is that, in some machines (Windows Domain Controllers), these cookies are not being used when I request resources in subdomains like `https://accounts.dev.example.com/health-check`, but according to the MDN docs a cookie for a domain can be used for requesting resources to subdomains:

*Domain=<domain-value> Optional*

Specifies those hosts to which the cookie will be sent. If not specified,
defaults to the host portion of the current document location (but not
including subdomains). Contrary to earlier specifications, leading dots in
domain names are ignored. **If a domain is specified, subdomains are always
included.**


Do you know how to properly configure `HttpClient` to pass the domain cookies to subdomain requests?

A bit more of details:

The cookies returned by my authentication service at `https://accounts.dev.example.com/login` look like this in the HTTP headers:

Set-Cookie: AK=112233;Version=1;Domain=.dev.example.com;Path=/;Max-Age=5400;Secure;HttpOnly, 
Set-Cookie: AS=445566;Version=1;Domain=.dev.example.com;Path=/;Max-Age=5400;Secure;HttpOnly, 

Then I can query C#'s `CookieContainer` with either of these calls in normal workstations:

cookies.GetCookies("https://accounts.dev.example.com")
cookies.GetCookies("https://dev.example.com")

Both of which will return the 2 cookies like:

$Version=1; AK=112233; $Path=/; $Domain=.dev.example.com
$Version=1; AS=445566; $Path=/; $Domain=.dev.example.com

But in the other machines (the Domain Controller's) the first call will return an empty list, while the second will return the 2 cookies.

Why this difference on the behaviour of CookieContainer.GetCookies depending on which machine is running the code?

My workstations are using `Microsoft Windows 10 Home Single Language (.Net 4.0.30319.42000)` and the DCs are using `Microsoft Windows Server 2012 R2 Datacenter (.Net 4.0.30319.36399)`.

Temporary solution

This is my solution so far, which works, but not sure if there is a proper way of solving the issue:

    foreach (Cookie cookie in cookies.GetCookies(new Uri("https://dev.example.com")))
    {
        cookies.Add(new Uri("https://accounts.dev.example.com"), new Cookie(cookie.Name, cookie.Value, cookie.Path, ".accounts.dev.example.com"));
    }

So, I'm duplicating the cookie for each one of the subdomains that my app should send these cookies to,

The code

This is a modified version of my code:

   public static async Task<string> DoAuth(CookieContainer cookies,
                                            Dictionary<string, string> postHeaders,
                                            StringContent postBody)
    {
        try
        {
            using (var handler = new HttpClientHandler())
            {
                handler.CookieContainer = cookies;
                using (var client = new HttpClient(handler, true))
                {
                    foreach (var key in postHeaders.Keys)
                        client.DefaultRequestHeaders.Add(key, postHeaders[key]);

                    var response = await client.PostAsync("https://accounts.dev.example.com/login", postBody);
                    response.EnsureSuccessStatusCode();
                    
                    // This line returns 0 in Domain Controllers, and 2 in all other machines
                    Console.Write(cookies.GetCookies("https://accounts.dev.example.com").Count);

                    return await response.Content.ReadAsStringAsync();
                }
            }
        }
        catch (HttpRequestException e)
        {
            ...
            throw;
        }
    }


Original questions:

解决方案

Hi MondKin,

Thank you for posting here.

Please try the ways below to set the subdomain.

Response.Cookies [ "domain" ] .Value = DateTime.Now.ToString();
Response.Cookies [ "domain" ] .Expires = DateTime.Now.AddDays(1);
Response.Cookies [ "domain" ] .Domain = "support.contoso.com" ;

support.contoso.com is the subdomain of www.contoso.com.

For more details, please refer to the MSDN document.

https://msdn.microsoft.com/en-us/library/ms178194.aspx

Best Regards,

Wendy


这篇关于域未用于子域的Cookie的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆