Совместное использование файлов cookie ASP.NET между поддоменами - PullRequest
30 голосов
/ 29 сентября 2011

У меня есть два сайта, оба в одном домене, но с разными поддоменами.
site1.mydomain.com site2.mydomain.com

После того, как я аутентифицировался на каждом, я смотрюна куки, включенные в последующий запрос, и они идентичны для каждого сайта.

Однако, если я захожу на первый сайт, а затем перехожу на другой, я ожидаю, что мой файл cookie с сайта 1 будет отправлен вместе с запросом на сайт 2, но это не так.Вот свойства моих файлов cookie.

При входе на сайт 1 этот файл cookie затем существует

Name = MySite 
Domain = 
Has Keys = False 
HttpOnly = False 
Path = / 
Value = 1C41854066B03D8CC5679EA92DE1EF427DAC65D1BA0E672899E27C57245C1F0B7E93AB01B5563363AB4815A8F4BDE9D293FD261E03F8E60B8497ABBA964D8D315CCE1C8DD220C7176E21DC361935CF6 
Expires = 1/1/0001 12:00:00 AM 

При входе на сайт 2 эти файлы cookie затем существуют.

Name = MySite 
Domain = 
Has Keys = False 
HttpOnly = False 
Path = / 
Value =    C8C69F87F993166C4D044D33F21ED96463D5E4EB41E1D986BF508DA0CBD5C2CA7D782F59F3BC96871108997E899FF7401C0D8615705BDB353B56C7E164D2302EE6731F41705016105AD99F4E0578ECD2 
Expires = 1/1/0001 12:00:00 AM 

Я установил домен для каждого (не отображается в файле cookie запроса, так как он необходим только на клиенте).Я удостоверился, что мои настройки форм для каждого идентичны. Я убедился, что мои настройки машинных ключей одинаковы в обеих веб-конфигурациях.

Я не знаю, почему это не работает.Насколько я могу сказать, что файл cookie содержит то, что клиент будет отправлять его для одного субдомена, а не для другого, когда они оба используют одни и те же файлы cookie авторизации?

Пожалуйста, прокомментируйте, если есть ещеИнформация, которую вы хотели бы видеть.Я боролся с этим уже два дня.Согласно этой статье это должно работать.

ОБНОВЛЕНИЕ: код добавлен

Вот мои настройки файла конфигурации для моей аутентификации.Это используется на обоих сайтах.

<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: Проблема найдена, решение неизвестно Кажется, что моя проблема связана с тем, что мой второй сайт является частьюлокальной интранет-зоны.Если я захожу на сайт 1 с помощью Firefox, он работает, но я должен ввести свои учетные данные Windows.Если я перехожу через IE, мои учетные данные выбираются автоматически, но файлы cookie не могут быть прочитаны сайтом2.Я могу задать это в другом вопросе.

Ответы [ 4 ]

16 голосов
/ 29 сентября 2011

установите для свойства домена значение ".mydomain.com" в каждом файле cookie двух сайтов поддоменов

подобно

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

Попробуйте

С уважением

9 голосов
/ 29 сентября 2011

Добавьте новый файл 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"/>

Для дополнительной безопасности вы также можете зашифровать ключ машины для дальнейшей защиты. .

4 голосов
/ 09 февраля 2013

Если вы используете проверку подлинности с помощью форм на всех ваших поддоменах, все, что вам нужно сделать, это добавить свойство domain=".mydomain.com" к узлу <forms> в вашем web.config

Обратите внимание на начальный периодв .mydomain.com

Это простое изменение само по себе сделает ваш файл cookie аутентификации действительным во всех поддоменах;не нужно вручную устанавливать какие-либо куки.

1 голос
/ 01 марта 2013

Я создал метод расширения 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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...