• 同一域名的ASP.NET网站实现Session共享


    Session共享主要保证两点:

    1. 前台Asp_SessionId的Cookie作用域为顶级域名,且值相同
    2. 后端Session公用同一源 通过自定义HttpModule可以实现这两个需求
        /// <summary>
        /// 自定义HttpModule,使调用本HttpModule的系统使用同一个SessionID(只限于同一个根域名),实现Session共享
        /// 需要在AppSetting里面配置Domain(根域名),在system.webServer下添加自定义modules add name = "MakeSessionIDOneOnly" type="Tools.MakeSessionIDOneOnly, Tools"
        /// </summary>
        public class MakeSessionIDOneOnly : IHttpModule
        {
            private string m_RootDomain = string.Empty;
    
            #region IHttpModule Members
    
            public void Dispose()
            {
    
            }
            
            /// <summary>
            /// Init函数主要让本系统对应的StateServer中的Session的s_uribase(可以理解为作用域)一致,统一设置为根域名,这样相当于多套系统统一使用一个Session/// </summary>
            /// <param name="context"></param>
            public void Init(HttpApplication context)
            {
                //1.获取根域名
                m_RootDomain = ConfigurationManager.AppSettings["Domain"];
                //2.获取System.Web.SessionState.OutOfProcSessionStateStore类
                Type stateServerSessionProvider = typeof(HttpSessionState).Assembly.GetType("System.Web.SessionState.OutOfProcSessionStateStore");
                //3.获取该类的静态字段s_uribase
                FieldInfo uriField = stateServerSessionProvider.GetField("s_uribase", BindingFlags.Static | BindingFlags.NonPublic);
    
                if (uriField == null)
                    throw new ArgumentException("UriField was not found");
                //object obj= uriField.GetValue(null);
    
                //4.设置s_uribase值为根域名
                uriField.SetValue(null, m_RootDomain);
                context.EndRequest += new System.EventHandler(context_EndRequest);
            }
    
            /// <summary>
            /// 上下文结束时让输出的cookie作用域一致,统一设置为根域名
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            void context_EndRequest(object sender, System.EventArgs e)
            {
                HttpApplication app = sender as HttpApplication;
                for (int i = 0; i < app.Context.Response.Cookies.Count; i++)
                {
                    if (app.Context.Response.Cookies[i].Name == "ASP.NET_SessionId")
                    {
                        app.Context.Response.Cookies[i].Domain = m_RootDomain;
                    }
                }
            }
    
            #endregion
        }
    

    Init方法可以实现所有使用本HttpModule的项目使用同一个源的Session,这样在输出ASP.NET_SessionId的cookie时就会是相同的值,但是Cookie作用域没办法修改。 在context_EndRquest方法中重新设定ASP.NET_SessionId的作用域为根域名即可。 在需要调用本Module的项目Web.Config中需要加入

      <system.web>
        <compilation debug="true" targetFramework="4.6.1"/>
        <httpRuntime targetFramework="4.6.1"/>
        <!--设定session状态服务器的存储位置,共享session的项目都要设置为同一位置-->
        <sessionState mode="StateServer" stateConnectionString="tcpip=127.0.0.1:42424" timeout="30"></sessionState>
        <!--设置session的加解密方法,共享session的项目必须设置相同-->
        <machineKey decryptionKey="FD69B2EB9A11E3063518F1932E314E4AA1577BF0B824F369" validationKey="5F32295C31223A362286DD5777916FCD0FD2A8EF882783FD3E29AB1FCDFE931F8FA45A8E468B7A40269E50A748778CBB8DB2262D44A86BBCEA96DCA46CBC05C3" validation="SHA1" decryption="Auto"/>
        <!--IIS6或者IIS7经典模式,引用session统一处理模块-->
        <httpModules>
          <add name="MakeSessionIDOneOnly" type="Tools.MakeSessionIDOneOnly,Tools"/>
        </httpModules>
      </system.web>
      <system.webServer>
        <modules>
          <!--IIS7集成模式,引用session统一处理模块-->
          <add name="MakeSessionIDOneOnly" type="Tools.MakeSessionIDOneOnly,Tools"/>
        </modules>
      </system.webServer>
      <appSettings>
        <!--要共享Session的项目必须设置同一根域名-->
        <add key="DOMAIN" value="localhost"/>
      </appSettings>
  • 相关阅读:
    串口调适
    取出不重复的6个数
    个人Windows 10必备软件以及浏览器必装插件等
    合肥工业大学宣城校区2018年-2019年第一学期(大三上学期)物联网工程专业资料汇总(含课件、个人实验报告、实验代码、课设报告等)
    合肥工业大学宣城校区2019年-2020年第二(大三下)学期物联网工程专业资料汇总(含课件、个人实验报告、实验代码、课设报告等)
    合肥工业大学宣城校区2020年-2021年第一(大四上)学期物联网工程专业资料汇总(含课件、个人实验报告、实验代码、课设报告等)
    软件工程-单元测试-计算机测试-复习札记
    8086汇编计算分段函数值
    C语言是开源的吗?C++是开源的吗?C语言、C++是两个开源的标准,而不是开源软件或其它
    合肥工业大学编译原理实验LR(1)文法分析完整Scala实现代码(Java封装GUI)与测试数据
  • 原文地址:https://www.cnblogs.com/zhoushiya/p/12107670.html
Copyright © 2020-2023  润新知