zoukankan      html  css  js  c++  java
  • asp.net 配置二级域名的共享session,并实现sso单点登录

    公司最近做了一个新网站。原先网站的网址是www.xxxx.com。新做的网站要部署到info.xxxx.com。这两个网站要实现单点登录。而新老网站本身机构的原因,对于登录状态的判断,说白了就是对于session的判断。只要能让两个网站的session共享。那就可以实现单点登录了。由于我们公司的两个网站都是在一台服务器上的,所以要用这个方法,必须要满足三个条件

    1. 两个网站同为二级域名

    2. 两个网站部署在同一台服务器上。

    3. session也保存在与网站同一台服务器上。

    好了,直接讲方法,能实现才是硬道理,等实现后再去搞明白其中的原理,

    操作步骤:

    1. 在webconfig中,对session进行配置。在<configuration>中的<system.web>添加如下代码

    <configuration>
      <system.web>
        <compilation debug="true" targetFramework="4.0" />
        <sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" cookieless="false" timeout="30" />
        <machineKey validationKey="89K2J3HKSDIFY32BJF98SD98WIUHWI9823HQ21LSN0XMNV0NSFK3OIU0A9SU923NJ2J43O04123JLNKCM0VXLASLQPQP2O34098385HSFKJH23OB" decryptionKey="EERY7N4MVCLSP03384U547DAVZCZ4252617273GGGSHSJS8834320ORLKDMNVBBG" validation="SHA1" decryption="AES" />
      </system.web>

    这几行代码做两件事,1.将sessionstate的mode改为“StateServer”。2.设置加密和解密规则。

    2. 打开本地服务--》找到“ASP.NET 状态服务”,默认是不启动的,我们这里要把它启动。原因是mode="StateServer"表示session将使用进程外 ASP.NET 状态服务来存储状态信息。这个就需要ASP.NET 状态服务的支持,所以必须要打开。如果是需要配置成使用远程服务器存储session,还需要修改注册表,去打开远程访问。这个方面内容自己可以网上百度,这里不赘述。

    3.创建一个类。如果网站是部署在IIS7及以上的必须将这个类创建在app_code下。否则会报错。如果是IIS7以下不太清楚。我这里的网站是部署在IIS7上的。所以必须创建在app_code文件夹下

        public class CookiesHttpModule : IHttpModule
        {
            #region IHttpModule 成员
    
            void IHttpModule.Dispose()
            {
                //throw new Exception("The method or operation is not implemented.");
            }
    
            void IHttpModule.Init(HttpApplication context)
            {
                context.EndRequest += new EventHandler(this.EndRequest);
            }
    
            #endregion
    
            private void EndRequest(object sender, EventArgs args)
            {
                HttpApplication application = sender as HttpApplication;
                for (int i = 0; i < application.Response.Cookies.Count; i++)
                {
                    if (application.Response.Cookies[i].Name == "ASP.NET_SessionId")
                        application.Response.Cookies[i].Domain = ".xxxx.com";
                }
            }
        }

    这个代码的含义是,把存放sessionid的cookies的domain,改成一级域名。如此一来就能共享存放sessionid的cookies了。

    4. 在webconfig的configuration节点中,添加如下代码,作用是将这个每次在访问链接的时候,能使用到这个类。这个配置方式是iis7及以上的配置方式。如果网站是在iis6及以下的,可以在configuration下的system.web中的httpModules进行配置

      <system.webServer>
        <modules>
          <add name="CookiesHttpModule" type="SSO2.App_Code.CookiesHttpModule,SSO2"/>
        </modules>
      </system.webServer>

    5.也是最后一步了。在Global.asax中添加如下方法。

            public override void Init()
            {
                base.Init();
                foreach (string moduleName in this.Modules)
                {
                    string appName = "APPNAME";
                    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);
                            }
                        }
                    }
                }
            }

    在你需要的网站,中都加入上述代码,就可以实现两个相同一级域名的网站间共享session

    PS:如果将sessionState mode 改为"StateServer"后,发现scriptmanager无效的话,可以将scriptmanager中的EnablePartialRendering属性改为"false"

    参考文献:http://www.cnblogs.com/zhangzhixiong/p/5573525.html

  • 相关阅读:
    day 15 小结
    python中的数据类型以及格式化输出
    编程语言简介
    计算机简介
    堆排
    Lock锁
    JVM入门
    Java中反射调用私有方法出现NoSuchMethodException
    1248. 统计「优美子数组」
    注解
  • 原文地址:https://www.cnblogs.com/tfiremeteor/p/6229148.html
Copyright © 2011-2022 走看看