web-dev-qa-db-fra.com

Partage des cookies ASP.NET entre les sous-domaines

J'ai deux sites, tous deux sur le même domaine, mais avec des sous-domaines différents.
site1.mydomain.com site2.mydomain.com

Une fois authentifié sur chacun, je regarde les cookies inclus dans la demande suivante et ils sont identiques pour chaque site.

Cependant, si je me connecte au premier site, puis navigue vers l'autre, je m'attends à ce que mon cookie du site 1 soit envoyé avec la demande à site2, mais ce n'est pas le cas. Voici les propriétés de mes cookies.

En se connectant à Site1, ce cookie existe alors

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

En se connectant à Site2, ces cookies existent alors.

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

J'ai défini le domaine sur chacun (n'apparaît pas dans un cookie de demande car il n'est nécessaire que sur le client). Je me suis assuré que mes paramètres de formulaires pour chacun sont identiques. Je me suis assuré que mes paramètres de clé machine sont les mêmes dans les deux configurations Web.

Je ne sais pas pourquoi cela ne fonctionne pas. Qu'est-ce qu'un cookie contient que le client l'enverra pour un sous-domaine et pas l'autre quand ils utilisent tous les deux les mêmes cookies d'authentification pour autant que je sache?

Veuillez commenter s'il y a plus d'informations que vous aimeriez voir. Je lutte avec ça depuis deux jours maintenant. Selon cet article cela devrait fonctionner.

MISE À JOUR: code ajouté

Voici mon paramètre de fichier de configuration pour mon authentification. Ceci est utilisé dans les deux sites.

<authentication mode="Forms">
    <forms loginUrl="~/Account/LogOn"
       defaultUrl="~/Home/Index"
       name="MySite" 
       protection="All" 
       path="/" 
       domain="mydomain.com" 
       enableCrossAppRedirects="true" 
       timeout="2880" 
/>

Et voici mon code pour créer le cookie dans 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);

MISE À JOUR 2:

J'ai remarqué quelque chose d'étrange lors des tests. Lorsque j'ajoute un cookie à la réponse pour site1, il est ajouté à ce répertoire ... C:\Users\jreddy\AppData\Roaming\Microsoft\Windows\Cookies

Lorsque j'ajoute un cookie à la réponse pour le site, il est ajouté à ce répertoire ... C:\Users\jreddy\AppData\Roaming\Microsoft\Windows\Cookies\Low

Ça pourrait être mon problème. Se pourrait-il que l'un de mes sites soit inclus dans la zone intranet locale?

MISE À JOUR 3: Problème trouvé, solution inconnue Il semble que mon problème soit lié à mon deuxième site faisant partie de la zone Intranet local. Si je vais sur Site1 à l'aide de Firefox, cela fonctionne, mais je dois saisir mes informations d'identification Windows. Si je passe par IE, mes informations d'identification sont récupérées automatiquement, mais les cookies ne peuvent pas être lus par site2. Je peux poser cette question dans une autre question.

30
Jeff Reddy

définir la propriété du domaine sur ".mydomain.com" dans chaque cookie de deux sites Web de sous-domaines

comme

Response.Cookies["test"].Value = "some value";
Response.Cookies["test"].Domain = ".mysite.com";

MISE À JOUR 1

dans le site

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

Sur le site B

HttpContext.Current.Request.Cookies["strName"].Value

Essayez-le

Cordialement

16
Mhmd

Ajouter un nouveau cookie et spécifier un domaine comme celui-ci

HttpCookie cookie = new HttpCookie("cookiename", "value");
cookie.Domain = "domain.com";

Pour l'authentification par formulaire, définissez-le dans web.config

<forms name=".ASPXAUTH" 
       loginUrl="login.aspx" 
       protection="All" 
       timeout="30" 
       path="/" 
       requireSSL="false" 
       domain="domain.com">
</forms>

Le cookie sera accessible à tous les sous-domaines.

Pour que chaque domaine déchiffre le cookie, tous les fichiers web.config doivent utiliser le même algorithme et la même clé de chiffrement/déchiffrement. ( comment créer une clé machine )

Exemple:

// 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"
/>

Pour des déploiements plus faciles, ces valeurs peuvent être stockées dans un fichier séparé:

<machineKey configSource="machinekey.config"/>

Pour plus de sécurité, vous pouvez également crypter la clé machine pour plus de protection. .

9
Prasanth

Si vous utilisez l'authentification par formulaire sur tous vos sous-domaines, il vous suffit d'ajouter domain=".mydomain.com" propriété à <forms> nœud dans votre web.config

Notez la première période dans .mydomain.com

Cette simple modification rendra votre cookie d'authentification valide dans tous les sous-domaines; pas besoin de définir manuellement des cookies.

4
roman m

J'ai créé une méthode d'extension HttpContext qui écrira un cookie sécurisé de sous-domaine.

Article de blog et discussion

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();
    }
}
1
Nick