跨子域共享 ASP.NET cookie

发布于 2024-12-06 18:57:39 字数 2474 浏览 0 评论 0原文

我有两个站点,都位于同一域,但具有不同的子域。

  • site1.mydomain.example
  • site2.mydomain.example

在每个站点上进行身份验证后,我会查看后续请求中包含的 cookie,它们对于每个站点都是相同的。

但是,如果我登录第一个站点,然后导航到另一个站点,我希望站点 1 中的 cookie 与请求一起发送到站点 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 发送给一个子域而不是另一个子域,那么 cookie 包含什么?

如果您想查看更多信息,请发表评论。我已经为此苦苦挣扎了两天。根据这篇文章,这应该有效。

添加的代码

这是我的身份验证的配置文件设置。这在两个站点中都使用。

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

这是我在 Site1 中创建 cookie 的代码。

//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.example";
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

这可能是我的问题。难道我的一个站点包含在本地 Intranet 区域中?

更新3:发现问题,解决方案未知 看来我的问题与我的第二个站点是本地 Intranet 区域的一部分有关。如果我使用 Firefox 访问 Site1,它可以工作,但我必须输入我的 Windows 凭据。如果我通过 IE,我的凭据会自动获取,但 site2 无法读取 cookie。我可能会在另一个问题中问这个。

I have two sites, both on the same domain, but with different sub-domains.

  • site1.mydomain.example
  • site2.mydomain.example

Once I'm authenticated on each, I look at the cookies included in subsequent request and they are identical for each site.

However, if I log into the first site, and then navigate to the other, I expect my cookie from site 1 to be sent with the request to site2, but this is not the case. Here are the properties of my cookies.

Logging into Site1, this cookie then exists

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

Logging into Site2, these cookies then exists.

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

I've set the domain on each (doesn't show up in a request cookie as it's only needed on the client).
I've made sure my Forms setting for each are identical
I've made sure my machine key settings are the same in both web configs.

I'm at a loss on why this isn't working. What is it that a cookie contains that the client will send it for one sub-domain and not the other when they are both using the same auth cookies so far as I can tell?

Please comment if there is more info you'd like to see. I've been struggling with this for two days now. According to this article this should be working.

code added

Here is my config file setting for my authentication. This is used in both sites.

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

And here is my code to create the cookie in 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.example";
HttpContext.Response.Cookies.Add(cookie);
HttpContext.Response.Redirect(site2Url,true);

UPDATE 2:

I noticed something strange while testing. When I add a cookie to the response for site1, it get's added to this directory...
C:\Users\jreddy\AppData\Roaming\Microsoft\Windows\Cookies

When I add a cookie to the response for site, it gets added to this directory...
C:\Users\jreddy\AppData\Roaming\Microsoft\Windows\Cookies\Low

That could be my problem. Could it be that one of my sites is included in the local intranet zone?

UPDATE 3: Problem found, solution unknown
It seems that my problem has to do with my second site being part of the Local Intranet Zone. If I go to Site1 using Firefox it works, but I have to enter my Windows credentials. If I go thru IE, my credentials are picked up automatically, but the cookies can't be read by site2. I may ask this in another question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦晓ヶ微光ヅ倾城 2024-12-13 18:57:39

将两个子域网站的Cookies中的Domain属性设置为.mydomain.example。喜欢:

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

在站点 A:

HttpCookie hc = new HttpCookie("strName", "value");
hc.Domain = ".mydomain.example"; // must start with "."
hc.Expires = DateTime.Now.AddMonths(3);
HttpContext.Current.Response.Cookies.Add(hc);

在站点 B:

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

Set the property of Domain to .mydomain.example in each Cookies of two subdomains websites. Like:

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

In Site A:

HttpCookie hc = new HttpCookie("strName", "value");
hc.Domain = ".mydomain.example"; // must start with "."
hc.Expires = DateTime.Now.AddMonths(3);
HttpContext.Current.Response.Cookies.Add(hc);

In Site B:

HttpContext.Current.Request.Cookies["strName"].Value
帥小哥 2024-12-13 18:57:39

添加新的 cookie 并指定域,如下所示

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

对于表单身份验证,在 web.config 中设置

<forms name=".ASPXAUTH"
       loginUrl="login.aspx"
       protection="All"
       timeout="30"
       path="/"
       requireSSL="false"
       domain="domain.example">
</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"/>

为了增强安全性,您还可以加密计算机密钥以提供进一步的保护。

Add new cookie and specify domain like this

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

For forms authentication set this in web.config

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

The cookie will be accessible to all the subdomains.

In order for each domain to decrypt the the cookie, all web.config files must use the same encryption/decryption algorithm and key. (how to create a machine key)

Example:

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

For easier deployments, these values can be stored in a separate file:

<machineKey configSource="machinekey.config"/>

For added security you can also encrypt the machine key for further protection..

你对谁都笑 2024-12-13 18:57:39

如果您在所有子域上使用表单身份验证,则只需将 domain=".mydomain.example" 属性添加到 web.config 中的 > 节点

注意 .mydomain.example 中的前导句点

这个简单的更改本身将使您的身份验证 cookie 在所有子域中有效;无需手动设置任何cookie。

If you're using Forms authentication on all of your sub domains, all you need to do is to add domain=".mydomain.example" property to the <forms> node in your web.config

Note the leading period in .mydomain.example

This simple change by itself will make your authentication cookie valid in all sub-domains; no need to manually set any cookies.

锦上情书 2024-12-13 18:57:39

我创建了一个 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();
    }
}

I've created a HttpContext extension method that will write a sub domain safe cookie.

Blog post and 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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文