【问题标题】:Store Session cookie for groups of subdomains in ASP.NET IIS7在 ASP.NET IIS7 中存储子域组的会话 cookie
【发布时间】:2011-01-06 05:16:47
【问题描述】:

我有一个运行 ASP.NET 的应用程序。我有不同的域和不同的子域。我希望这些域与其子域共享会话。

例如,以下域访问此应用程序:
www.example1.com
print.example1.com
www.example2.com
print.example2.com

如果用户访问 www.example1.com 和 print.example1.com,我希望它使用相同的会话。如果用户要访问 www.example2.com 和 print.example2.com,我希望它使用与 *.example1.com 不同的会话。

我过去处理它的方式是在 IIS6 中完美运行的 page_load 中的 hack:
Response.Cookies["ASP.NET_SessionId"].Value = Session.SessionID;
Response.Cookies["ASP.NET_SessionId"].Domain = SiteUtility.GetCookieDomain();
(SiteUtility.GetCookieDomain 会根据请求的 url 返回 .example1.com 或 .example2.com)

不幸的是,这似乎不再适用于 iis7。用户访问的每个子域/域,用户都会获得一个新的会话 cookie。

然后我找到了 web.config 条目:
'

这非常适合在 example1.com 子域之间共享会话 cookie。不幸的是,这完全搞砸了 *.example2.com 的会话状态。

关于如何解决这个问题的任何想法?

【问题讨论】:

  • 感谢大家的帮助。我确定其中一个子域在 ie8 中处于受信任状态,而另一个则不是。当两者都处于受信任状态(并且可能都处于不受信任状态)时,它可以工作。泡利在这方面和我一起度过的时间最多,所以我想把答案归功于他。

标签: c# asp.net session cookies web-config


【解决方案1】:

您是否尝试过创建一个HttpModule 来拦截EndRequest 事件,遍历Response.Cookies 集合,找到会话库并在实际发送到客户端之前更改其Domain 属性。

编辑:

Kevin 最后确定其中一个子域在 ie8 中处于受信任状态,而另一个则不是。当两者都处于受信任状态(并且可能都处于不受信任状态)时,它可以工作。我确实花了最多时间在这上面,所以 Kevin 想把答案归功于我。

【讨论】:

  • 我如何确定 cookie 会在 beginrequest 中被读取?我想创建第二个迭代请求的 httpModule 吗? (阅读 httpmodules...)
  • 您不需要关心 BeginRequest... 您需要做的就是确保发送给客户端的 cookie 设置了正确的域,不是吗?不过,对于您的问题,您可以指示单个模块响应您需要的所有事件。
  • 我创建了我的 httpmodule 并且它被正确调用。不幸的是,它仍然无法跨域工作。奇怪的是,我上面的 hack 在 iis6 中完美运行。
  • fiddler怎么说,服务器发过来的cookie的实际内容是什么?
  • 设置 Cookie:MyCustomCookie=xt35oxia3mfvmzehz0r0v445;域=.example1.com;过期=星期四,2011 年 1 月 6 日 07:19:06 GMT;路径=/; HttpOnly
【解决方案2】:

而不是使用 SiteUtility.GetCookieDomain(),尝试使用:

var domainSansTLD = Request.Url.Host.Replace(".com", "");
var secondLevelDomain = domainSansTLD.Substring(domainSansTLD.LastIndexOf('.'));
var cookieDomain = secondLevelDomain + ".com";

【讨论】:

  • Pauli 是正确的,将它放在 HttpModule 的 EndRequest 中会比在 page_load 中干净得多
  • GetCookieDomain 几乎可以做到这一点哇,这看起来很糟糕...... public static string GetCookieDomain() { Uri url = System.Web.HttpContext.Current.Request.Url;字符串域 = url.DnsSafeHost; string[] splitDomain = domain.Split('.'); int splitCount = splitDomain.Count(); System.Text.StringBuilder retVal = new System.Text.StringBuilder(); for (int i = 1; i
【解决方案3】:

第一种方式,

将会话作为文件存储在两个服务器都可以访问的位置(这对于虚拟服务器或共享文件夹很有用)。这种方法有点不可靠,共享文件夹和延迟会导致问题。

好的,我本来打算写一些其他方法,但我相信它们会被发布,因为他们对 asp.net 的了解比我多,但是,我确实有个人偏好,我认为会是不错的选择。

此选项将是一个内存缓存服务器。本质上,它是一个在 RAM 上运行的数据库,您将所有会话都指向它(tcp://mem.domain.com:1234 ...抱歉,我不记得我头顶上的常用端口)。

希望对你有所帮助

乔恩

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-12
    • 1970-01-01
    • 1970-01-01
    • 2010-10-01
    • 2014-11-05
    • 2015-05-22
    • 2023-03-25
    • 2014-12-30
    相关资源
    最近更新 更多