ASP.Net二級域名站點共享Session狀態
我的前面一篇文章提到了如何在使用了ASP.Net form authentication的二級站點之間共享登陸狀態,http://www.cnblogs.com/jzywh/archive/2007/09/23/902905.Html,
今天, 我要寫的是如何在二級域名站點之間,主站點和二級域名站點之間共享Session。
首先, Session要共享,站點之間SessionID必須要一致,那怎麼保證SessionID一致呢?
ASP.NET中的SessionID是存儲在客戶端的cookIE之中鍵值為ASP.NET_SessionId用來維護浏覽者Session對應關系的一個字符串,要想在二級域名站點之間,主站點和二級域名站點共享SessionID就必須先共享,那麼我們就必須先實現ASP.Net_SessionId這一cookIE的共享。
A: CrossDomainCookIEModule
------------------------------------------------------------------------------------------------
public class CrossDomainCookIE : IHttpModule
{
private string m_RootDomain = string.Empty;
#region IHttpModule Members
public void Dispose()
{
}
public void Init(HttpApplication context)
{
m_RootDomain = ConfigurationManager.APPSettings["RootDomain"];
context.EndRequest += new System.EventHandler(context_EndRequest);
}
void context_EndRequest(object sender, System.EventArgs e)
{
HttpApplication app = sender as HttpApplication;
for (int i = 0; i < app.Context.Response.CookIEs.Count; i++)
{
app.Context.Response.CookIEs[i].Domain = m_RootDomain;
}
}
#endregion
}
上面的Module重設了所有cookie的domain到root domain, root domain在web.config中設置。也許有人會說這是眉毛胡子一把抓重寫了所有cookie的domain, 那他也可以判斷一下cookIE的name, 如果為ASP.Net_SessionId的話才重寫。
如果主站點和二級域名站點是同一站點,那麼做到這一步,你的session就已經共享了,因為Session的ID是相同的,而且Session容器也是同一個。
如果主站點和二級域名站點是兩個不同站點,則需要進行更多的操作了。
如果兩個站點是不同的服務器的話,解決方法要簡單點:
1) 使用相同的state server來存儲Session.
2) 在兩個站點的web.config設置相同的MachineKey.
<MachineKey
validationKey="78AE3850338BFADCE59D8DDF58C9E4518E7510149C46142D7AAD7F1AD49D95D4"
decryptionKey="5FC88DFC24EA123C"
validation="SHA1"/>
MachineKey的設置請參考http://msdn.microsoft.com/zh-cn/ASP.Net/w8h3skw9.ASPx
3) 給兩個站點設置相同nam
e
這樣做是為了確保兩個站點的siteID相同,siteID是site name的hash值,注意請不要使用默認站點,因為默認站點的siteID並非site name的hash.
如果兩個站點是在同一的服務器的話,需要對CrossDomainCookIE再作一下修改,此方法也可應用於兩個站點在不同服務器的情況:
1) 使用相同的state server來存儲Session.
2) 用反射來設置System.Web.SessionState.OutOfProcSessionStateStore的靜態字段s_uribase的值
public class CrossDomainCookIE : IHttpModule
{
private string m_RootDomain = string.Empty;
#region IHttpModule Members
public void Dispose()
{
}
public void Init(HttpApplication context)
{
m_RootDomain = ConfigurationManager.APPSettings["RootDomain"];
Type stateServerSessionProvider = typeof(HttpSessionState).Assembly.GetType("System.Web.SessionState.OutOfProcSessionStateStore");
FieldInfo uriField = stateServerSessionProvider.GetFIEld("s_uribase", BindingFlags.Static | BindingFlags.NonPublic);
if (uriFIEld == null)
throw new ArgumentException("UriFIEld was not found");
uriFIEld.SetValue(null, m_RootDomain);
context.EndRequest += new System.EventHandler(context_EndRequest);
}
void context_EndRequest(object sender, System.EventArgs e)
{
HttpApplication app = sender as HttpApplication;
for (int i = 0; i < app.Context.Response.CookIEs.Count; i++)
{
app.Context.Response.CookIEs[i].Domain = m_RootDomain;
}
}
#endregion
}
完成這樣的修改之後就可以實現Session的共享了。
同樣如果你是使用SQL Server來存儲Session, 也可以使用類似的方法來解決Session共享問題。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.Net/nutian/archive/2008/11/08/3254149.ASPx