Cookie для домена не используется для поддоменов
Я использую HttpClient
в моем приложении, чтобы отправить мой пользователь / пароль в службу, которая возвращает некоторые куки, которые я могу позже использовать для всех других моих запросов. Сервис находится по адресу https://accounts.dev.example.com/login
и возвращает два куки, которые имеют Domain=.dev.example.com
, Проблема, которую я обнаружил, заключается в том, что на некоторых компьютерах (контроллеры домена Windows) эти файлы cookie не используются, когда я запрашиваю ресурсы в таких поддоменах, как https://accounts.dev.example.com/health-check
, но в соответствии с документами MDN для запроса ресурсов к поддоменам может использоваться файл cookie для домена:
Домен = Необязательно
Указывает те хосты, на которые будет отправлен куки. Если не указан, по умолчанию используется хост-часть текущего местоположения документа (но не включая поддоменов). В отличие от более ранних спецификаций, начальные точки в доменных именах игнорируются. Если указан домен, субдомены всегда включаются.
Вы знаете, как правильно настроить HttpClient
передать куки домена на запросы поддоменов?
Немного больше деталей:
Файлы cookie, возвращенные моей службой аутентификации на https://accounts.dev.example.com/login
выглядеть так в заголовках 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 куки, как:
$Version=1; AK=112233; $Path=/; $Domain=.dev.example.com
$Version=1; AS=445566; $Path=/; $Domain=.dev.example.com
Но на других машинах (контроллере домена) первый вызов вернет пустой список, а второй вернет 2 куки.
Почему такая разница в поведении 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;
}
}
1 ответ
Поскольку я не мог найти ответ на этот вопрос (не в TechNet), я решил использовать следующее решение, которое работает, но не уверен, существует ли правильный способ решения проблемы:
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"));
}
Итак, я дублирую куки для каждого из поддоменов, куда мое приложение должно отправлять эти куки.
Основная проблема, похоже, связана с ошибкой в заголовке Set-Cookie. Похоже, причина проблемы вVersion=
компонент в Set-Cookie
заголовок. Это заставляет CookieContainer падать лицом вниз и приводит к странному$Version
а также $Domain
файлы cookie затем отправляются в последующих клиентских запросах. Насколько я могу судить, удалить эти испорченные файлы cookie тоже невозможно. ИтерацияGetCookies()
с исходным доменом не обнаруживает ошибочные файлы cookie.