使用asp.net和状态服务器在两个网站之间共享会话

在IIS 7.5下,我有两个完全相同的网站托管在两台不同的机器上。 ASP.NET状态服务正在我的机器上运行,web.config在两个站点中都使用以下代码更新:

 

允许远程连接在注册表中设置为1,以便第二个网站访问状态服务器。

两个网站都具有相同的机器密钥:

  

此外,两个站点在IIS中配置为具有相同的标识符。

我想要做的是这两个站点共享相同的会话数据,例如能够执行以下操作:

 // At web site 1: Session["key"] = "value" 

 // At web site 2: // Read session value from the other web site string result = Session["key"] 

问题是我无法完成这个测试,真的无法理解我做错了什么。

任何可能有帮助的想法?

您需要一种方法来说服您的浏览器发送相同的ASP.NET会话cookie,无论它访问哪个站点。

如果请求中不存在cookie,则将使用该密钥创建新会话。

我认为你可以通过一些偷偷摸摸的DNS配置让浏览器保留密钥 – 如果你指定http://website1.mydomain.com/和http://website2.domain.com/作为你网站的地址,那么将ASP.NET会话cookie的域设置为“domain.com”,然后您的浏览器将其发送到两个站点并且应该共享会话。

您也可以在ASP.NET中使用cookieless模式,并从生成的URL中获取会话ID。

我知道这个问题在5年前得到了解答,但今天我想我可以提供一些更多的信息。

首先,这不是在两个IIS应用程序之间共享会话数据的官方方式,也不是最流行的方式。 “看似官方”的方式是使用SQL Server会话 。

如果您因任何原因无法使用SQL服务器,那么我们可以稍微调整一下IIS应用程序,以便我们可以使用进程外会话,即StateServer会话状态模式。

为了使它有效,有很多事情要做:

  1. 2应用程序的会话cookie必须设置在同一域名。 例如
  
  1. 必须匹配机器密钥。 您可以执行标准的Web.config字段加密以使其更安全,但这是可选的。
  
  1. 会话状态模式设置为状态服务器

将(1),(2),(3)放在一起:

     ... 
  1. 必须匹配应用程序名称 。 如果不是,则只能共享会话ID,而不能共享会话数据。 问题是您无法在Web.config中配置应用程序名称。 然而,我们可以创建自己的配置然后通过reflection注入它。 只需将以下代码放在Global.asax.cs中:

     public override void Init() { base.Init(); try { // Get the app name from config file... string appName = ConfigurationManager.AppSettings["ApplicationName"]; if (!string.IsNullOrEmpty(appName)) { foreach (string moduleName in this.Modules) { IHttpModule module = this.Modules[moduleName]; SessionStateModule ssm = module as SessionStateModule; if (ssm != null) { FieldInfo storeInfo = typeof(SessionStateModule).GetField("_store", BindingFlags.Instance | BindingFlags.NonPublic); SessionStateStoreProviderBase store = (SessionStateStoreProviderBase)storeInfo.GetValue(ssm); if (store == null) //In IIS7 Integrated mode, module.Init() is called later { FieldInfo runtimeInfo = typeof(HttpRuntime).GetField("_theRuntime", BindingFlags.Static | BindingFlags.NonPublic); HttpRuntime theRuntime = (HttpRuntime)runtimeInfo.GetValue(null); FieldInfo appNameInfo = typeof(HttpRuntime).GetField("_appDomainAppId", BindingFlags.Instance | BindingFlags.NonPublic); appNameInfo.SetValue(theRuntime, appName); } else { Type storeType = store.GetType(); if (storeType.Name.Equals("OutOfProcSessionStateStore")) { FieldInfo uribaseInfo = storeType.GetField("s_uribase", BindingFlags.Static | BindingFlags.NonPublic); uribaseInfo.SetValue(storeType, appName); } } } } } } catch (Exception ex) { log.Error(ex.Message, ex); } } 

    积分转到pfemiani , Li Chen ,以及我不记得是谁在一个代码项目的评论中把它放在一起。 请注意,pfemiani的答案对我不起作用,但将它与李晨的post结合起来了。

  2. 确保ASP .NET状态服务正在运行。 这是会话数据现在保存的地方。

两个asp.net Web应用程序之间的共享会话

请参考以下url

http://www.freshcodehub.com/Article/48/sharing-session-between-two-aspnet-web-applications