域名的Cookie未用于子域名

时间:2018-06-07 17:58:20

标签: c# cookies setcookie domaincontroller

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

  

Domain = Optional

     

指定要将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

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

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

$Version=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)

代码

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

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;
    }
}

2 个答案:

答案 0 :(得分:0)

由于我找不到答案(也没有在TechNet中找到答案),我决定采用以下可行的解决方案,但不确定是否有解决此问题的适当方法:

set

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

答案 1 :(得分:0)

基本问题似乎是Set-Cookie标头中的错误。造成此问题的原因似乎是Version=标头中的Set-Cookie组件。这使得CookieContainer掉到了最前面,并导致奇怪的$Version$Domain Cookie,然后在后续的客户端请求中发送。据我所知,也无法删除这些损坏的Cookie。使用原始域迭代GetCookies()不会显示错误的Cookie。