ASP.NET二级域名站点共享Session状态

作者: 江大鱼 发表于 2008-11-02 14:17 原文链接 阅读: 2489 评论: 16

我的前面一篇文章提到了如何在使用了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的共享。

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
 }
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

 

上面的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的设置请参考http://msdn.microsoft.com/zh-cn/asp.net/w8h3skw9.aspx

3) 给两个站点设置相同name

这样做是为了确保两个站点的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
    }
.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; }

 

完成这样的修改之后就可以实现Session的共享了。

 

同样如果你是使用SQL server来存储Session, 也可以使用类似的方法来解决Session共享问题。


示例文件下载  http://files.cnblogs.com/jzywh/ShareSessionSample.zip

评论: 16 查看评论 发表评论

百度期待您的加盟

最新新闻:
· 分析:雅虎与谷歌新闻战略之争(2010-07-11 15:14)
· 百度今日赴硅谷为框计算招聘顶级工程师(2010-07-11 15:08)
· 团购网站的末日(2010-07-11 14:19)
· 纸和笔的小众需求(2010-07-11 13:45)
· 涂雅速涂:黑客在行动,唐峻很郁闷(2010-07-11 13:07)

编辑推荐:Swifter C#之inline还是不inline,这是个问题

网站导航:博客园首页  个人主页  新闻  闪存  小组  博问  社区  知识库

你可能感兴趣的:(ASP.NET二级域名站点共享Session状态)