Совместное использование куки файлов ASP.NET в поддоменах
У меня есть два сайта, как в одном домене, так и в разных поддоменах.
site1.mydomain.com
site2.mydomain.com
Как только я аутентифицирован для каждого, я просматриваю файлы cookie, включенные в следующий запрос, и они идентичны для каждого сайта.
Однако, если я запишусь на первый сайт, а затем перейду к другому, я ожидаю, что мой файл cookie с сайта 1 будет отправлен с запросом на сайт2, но это не так. Вот свойства моих файлов cookie.
Вход в Site1, этот файл cookie существует
Name = MySite
Domain =
Has Keys = False
HttpOnly = False
Path = /
Value = 1C41854066B03D8CC5679EA92DE1EF427DAC65D1BA0E672899E27C57245C1F0B7E93AB01B5563363AB4815A8F4BDE9D293FD261E03F8E60B8497ABBA964D8D315CCE1C8DD220C7176E21DC361935CF6
Expires = 1/1/0001 12:00:00 AM
Войдя в Site2, эти файлы cookie существуют.
Name = MySite
Domain =
Has Keys = False
HttpOnly = False
Path = /
Value = C8C69F87F993166C4D044D33F21ED96463D5E4EB41E1D986BF508DA0CBD5C2CA7D782F59F3BC96871108997E899FF7401C0D8615705BDB353B56C7E164D2302EE6731F41705016105AD99F4E0578ECD2
Expires = 1/1/0001 12:00:00 AM
Я установил домен на каждом (не отображается в файле cookie запроса, поскольку он нужен только для клиента).
Я убедился, что мои настройки форм для каждого идентичны
Я убедился, что мои настройки машинного ключа одинаковы в обеих веб-конфигурациях.
Я не понимаю, почему это не работает. Что такое cookie, что клиент отправит его для одного поддомена, а не другого, когда они оба используют одни и те же файлы cookie, насколько я могу сказать?
Прокомментируйте, если есть дополнительная информация, которую вы хотели бы видеть. Я боролся с этим уже два дня. Согласно этой статье, это должно работать.
UPDATE: добавлен код
Вот мой параметр файла конфигурации для моей аутентификации. Это используется на обоих сайтах.
<authentication mode="Forms">
<forms loginUrl="~/Account/LogOn"
defaultUrl="~/Home/Index"
name="MySite"
protection="All"
path="/"
domain="mydomain.com"
enableCrossAppRedirects="true"
timeout="2880"
/>
И вот мой код для создания файла cookie в Site1.
//Add a cookie that the Site2 will use for Authentication
var cookie = FormsAuthentication.GetAuthCookie(userName, true);
cookie.Name = "MySite";
cookie.HttpOnly = false;
cookie.Expires = DateTime.Now.AddHours(24);
cookie.Domain = "mydomain.com";
HttpContext.Response.Cookies.Add(cookie);
HttpContext.Response.Redirect(site2Url,true);
ОБНОВЛЕНИЕ 2:
Я заметил что-то странное во время тестирования. Когда я добавляю cookie в ответ на site1, он добавляется в этот каталог... C:\Users\jreddy\AppData\Roaming\Microsoft\Windows\Cookies
Когда я добавляю файл cookie для ответа на сайт, он добавляется в этот каталог... C:\Users\jreddy\AppData\Roaming\Microsoft\Windows\Cookies\Low
Это может быть моей проблемой. Может быть, один из моих сайтов включен в зону локальной интрасети?
ОБНОВЛЕНИЕ 3: найдена проблема, неизвестно решение
Похоже, что моя проблема связана с тем, что мой второй сайт является частью зоны локальной интрасети. Если я перейду на Site1 с помощью Firefox, он будет работать, но я должен ввести учетные данные Windows. Если я перейду через IE, мои учетные данные будут автоматически загружены, но файлы cookie не могут быть прочитаны сайтом2. Я могу задать это в другом вопросе.
Ответы
Ответ 1
установить свойство Domain в ".mydomain.com" в каждом файле cookie двух субдоменов
like
Response.Cookies["test"].Value = "some value";
Response.Cookies["test"].Domain = ".mysite.com";
ОБНОВЛЕНИЕ 1
на сайте
HttpCookie hc = new HttpCookie("strName", "value");
hc.Domain = ".mydomain.com"; // must start with "."
hc.Expires = DateTime.Now.AddMonths(3);
HttpContext.Current.Response.Cookies.Add(hc);
На сайте B
HttpContext.Current.Request.Cookies["strName"].Value
Попробуйте
Привет
Ответ 2
Добавить новый файл cookie и указать домен, подобный этому
HttpCookie cookie = new HttpCookie("cookiename", "value");
cookie.Domain = "domain.com";
Для проверки подлинности форм установите это в web.config
<forms name=".ASPXAUTH"
loginUrl="login.aspx"
protection="All"
timeout="30"
path="/"
requireSSL="false"
domain="domain.com">
</forms>
Файл cookie будет доступен для всех поддоменов.
Чтобы каждый домен расшифровывал файл cookie, все файлы web.config должны использовать один и тот же алгоритм шифрования/дешифрования и ключ. (как создать машинный ключ)
Пример:
// do not wrap these values like this in the web.config
// only wrapping for code visibility on SO
<machineKey
validationKey="21F090935F6E49C2C797F69BBAAD8402ABD2EE0B667A8B44EA7DD4374267A75
D7AD972A119482D15A4127461DB1DC347C1A63AE5F1CCFAACFF1B72A7F0A281
B"
decryptionKey="ABAA84D7EC4BB56D75D217CECFFB9628809BDB8BF91CFCD64568A145BE59719
F"
validation="SHA1"
decryption="AES"
/>
Для упрощения развертывания эти значения могут быть сохранены в отдельном файле:
<machineKey configSource="machinekey.config"/>
Для дополнительной защиты вы также можете зашифровать машинный ключ для дальнейшей защиты..
Ответ 3
Если вы используете проверку подлинности на всех ваших поддоменах, все, что вам нужно сделать, это добавить свойство domain=".mydomain.com"
в <forms>
node в web.config
Обратите внимание на начальный период в .mydomain.com
Это простое изменение само по себе сделает ваш cookie проверки подлинности действительным во всех поддоменах; нет необходимости вручную устанавливать файлы cookie.
Ответ 4
Я создал метод расширения HttpContext, который напишет безопасный файл cookie поддомена.
Запись в блоге и обсуждение
public static class HttpContextBaseExtenstions
{
public static void SetSubdomainSafeCookie(this HttpContextBase context, string name, string value)
{
var domain = String.Empty;
if (context.Request.IsLocal)
{
var domainSegments = context.Request.Url.Host.Split('.');
domain = "." + String.Join(".", domainSegments.Skip(1));
}
else
{
domain = context.Request.Url.Host;
}
var cookie = new HttpCookie(name, value)
{
Domain = domain
};
context.Response.SetCookie(cookie);
}
}
// usage
public class MyController : Controller
{
public ActionResult Index()
{
this.Context.SetSubdomainSafeCookie("id", Guid.NewGuid().ToString());
return View();
}
}