• Asp.Net StateServer实现共同域名下Session共享


    概述

        在实验的时候,参照了多方的信息,确实成功了,这里简单记录一下。

        我们知道,在Asp.Net的Web.Config文件中,System.Web节点下,有个sessionState节点,它说明了应用程序的Session处理方式,它有如下几个选项:

     

        MSDN对其分别作简单的解释:

        (MSDN地址:https://msdn.microsoft.com/zh-cn/library/h6bb9cz9(VS.80).aspx)

    说明

    Custom

    会话状态将使用自定义数据存储区来存储会话状态信息。

    InProc

    会话处于正在处理 ASP.NET 辅助进程的状态。这个辅助进程是:aspnet_state.

    Off

    会话状态被禁用。

    SQLServer

    会话状态将使用进程外 SQL Server 数据库来存储状态信息。

    StateServer

    会话状态将使用进程外 ASP.NET 状态服务来存储状态信息。

        我们今天要说的是StateSerrer方式,我们采取远程服务器的aspnet_state进程来集中管理多台服务器的Session。

    概述

        路径:HKEY_LOCAL_MACHINESYSTEMCurrentControlSetservicesaspnet_stateParameters

      

        将AllowRemoteConnection的值设置为1.

        注意:配置完成后要在服务管理器中重启aspnet_state这个服务.

    第二步:配置的Web.config来指定Session服务器地址和连接参数

       1.配置应用服务器Web.Configsystem.web下的SessionState节点

          <sessionState cookieless="UseCookies" mode="StateServer" stateConnectionString="tcpip=192.168.5.2:42424" timeout="20"/>

          其中:mode一定是StateServer

          StateConnectionString是tcpip=Session服务器IP:端口的格式,tcpip指应用服务器与Session服务器交流Session数据时采用的传输方式,Session服务器就不说了,端口默认是42424.

     

       2.配置应用服务器下system.web下的machineKey 节点

         <machineKey validationKey="7285450293EE699F349F7DB9BEA1F0B9EE1F045F" decryptionKey="73035EE41002AFB88D12A1B08559389CA351359A232649B3" validation="SHA1" />

         这个machineKey的值可以是随意的,但应用服务器和Sessione服务器一定要配成一样的,因为需要用它来给session进行解密。

    情况1:设置Session的域----同域名(www.a.com)访问

        因为stateserver会把这些要共享session放置到 appdomin的情况来区分,而appdomain是根据网站的标识ID来区分的,因此我们只需要共享Session的应用服务器的域设置成一样即可。当共享Session的应用均是www.a.com时,我们可以在自定义IHttpModule中,在request结束的事件中,改写ASP.NET_SessionId的cookie的 domain为这些网站的主域名即可。如下所示(转自:http://sai5d.blog.163.com/): 

    public class ShareSessionModule : IHttpModule
        {
            #region IHttpModule 成员
    
            void IHttpModule.Init(HttpApplication context)
            {
                context.EndRequest += new EventHandler(this.EndRequest);
            }
    
    
            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 = ".test.com";
                }
            }
    
            #endregion
        }
    View Code

    情况2:设置Session的域----跨域名(www.a.comwww.b.com)访问概述

        共享的网站是跨域名了,如www.a.comwww.b.com ,按照情况1的思路,现在Session在服务器是存在两个appdomain中了,这样我们就不能共享Session了。但,我们可以通过反射修改 OutOfProcSessionStateStore类中静态成员s_uribase来实现我们的目的,它是state外部存储需要访问的appdomain的一个内部id(其实就是多个appdomain映射为一个内部id,这个id就是s_uribase)。只要在创建session前,设置一个相同的appdomain的id,这样就能确保取session和放置session都到同一个 appdomain中,这个id可以随意设置。如下所示(转自:http://sai5d.blog.163.com/): 

    public class ShareSessionModule : IHttpModule
        {
    
            #region IHttpModule 成¨¦员
    
            void IHttpModule.Dispose()
            {
                //throw new Exception("The method or operation is not implemented.");
            }
    
            void IHttpModule.Init(HttpApplication context)
            {
                //throw new Exception("The method or operation is not implemented.");
                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, ".test.com");
                context.EndRequest += new EventHandler(this.EndRequest);
    
            }
    
    
            private void EndRequest(object sender, EventArgs args)
            {
                HttpApplication application = sender as HttpApplication;
    
                for (int i = 0; i < application.Response.Cookies.Count; i++)
                {
    
                    application.Response.Cookies[i].Domain = ".test.com";
                }
            }
    
            #endregion
        }
    View Code

    第三步:将自定义HttpModule加入Web.config 

    <httpModules>
       <add name="CookieTest" type="WebApplication1. ShareSessionModule,WebApplication1"/>
    </httpModules>

    参考文档

         http://sai5d.blog.163.com/blog/static/62225483201010211393132/

         https://msdn.microsoft.com/zh-cn/library/h6bb9cz9(VS.80).aspx

  • 相关阅读:
    git命令log与reflog的比较
    git基础仓库提交到新仓库,保存老仓库历史,并同步老仓库跟新到新仓库中
    classpath*与classpath
    fastjson将对象和json互转,@JSONField的使用及不生效
    feign接口自动生成工具
    IIS .Net Core 413错误和Request body too large解决办法
    thinphp 上传文件到七牛
    php 整合微信、支付宝扫码付款
    Jenkins:整合SonarQube8
    Jenkins:流水线打包运行boot项目
  • 原文地址:https://www.cnblogs.com/gudi/p/6525045.html
Copyright © 2020-2023  润新知