Share Session between two web sites using asp.net

2020-01-27 04:42发布

问题:

I have two exactly the same web sites hosted in two different machines under IIS 7.5. ASP.NET state service is running on my machine and the web.config is updated in both sites with the following code:

<sessionState mode="StateServer" stateConnectionString="tcpip=192.168.1.77:42424" cookieless="false" timeout="120"/>

The allow remote connection is set to 1 in registry in order for the second web site to access the state server.

Both web sites have the same machine key:

<machineKey validationKey="7CB8DF6872FB6B35DECD3A8F55582350FEE1FAB9BE6B930216056C1B5BA69A4C5777B3125A42C4AECB4419D43EC12F168FD1BB887469798093C3CAA2427B2B89" decryptionKey="02FC52E4C71544868EE297826A613C53537DF8FDAF93FA2C64E9A5EF0BA467FB" validation="SHA1" decryption="AES" />

Additionally both sites are configured in IIS to have the same Identifier.

What I want to do is that both these sites share the same session data for example being able to do the following:

// At web site 1: 
Session["key"] = "value"

and

// At web site 2:
// Read session value from the other web site
string result = Session["key"]

The problem is that I can't manage to accomplish this test and really can't understand what I am doing wrong.

Any idea that might help?

回答1:

You'll need a way to convince your browser to send the same ASP.NET session cookie regardless of which site it visits.

If the cookie isn't present on the request, then a new session will get created with that key.

I think you can get the browser to retain the key with some sneaky DNS configs - if you assign http://website1.mydomain.com/ and http://website2.domain.com/ to be the addresses of your sites, then set the domain of the ASP.NET session cookie to "domain.com", then your browser will send it to both sites and the session should be shared.

You may also be able to use cookieless mode with ASP.NET, and grab the session ID from the generated URLs.



回答2:

I'm aware that this question was answered 5 years ago, yet today I think I can put some more information into it.

First, this is not the official way to share session data between 2 IIS applications, or the most popular way. The "seemingly official" way is to use SQL Server session.

In case you can't use SQL server for any reason, then we can tweak the IIS applications a bit so that we can use Out-of-process session, aka StateServer session state mode.

To make it works, there are quite a few things to make right:

  1. Session cookie of 2 application must be set at same domain name. E.g.
<httpCookies domain=".your.site"/>
  1. Machine key must be matched. You can do standard Web.config field encryption to make it more secure, but that's optional.
<machineKey validationKey="[your_key]" 
    decryptionKey="[your_decryption_key]" validation="SHA1" />
  1. Session state mode set to state server

Putting (1), (2), (3) together:

<system.web>
    <httpCookies domain=".your.site"/>
    <machineKey validationKey="your_key" decryptionKey="your_decryption_key" validation="SHA1" />
    <sessionState mode="StateServer" timeout="60" />
    ...
  1. Application name must be matched. If not, only the session ID could be shared, but not session data. The problem is that you cannot configure your application name inside Web.config. Yet we can create our own configuration then inject it by reflection. Just put the following code in Global.asax.cs:

    public override void Init()
    {
        base.Init();
        try
        {
            // Get the app name from config file...
            string appName = ConfigurationManager.AppSettings["ApplicationName"];
            if (!string.IsNullOrEmpty(appName))
            {
                foreach (string moduleName in this.Modules)
                {
                    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);
                            }
                        }
                    }
                }
            }
    
        }
        catch (Exception ex)
        {
            log.Error(ex.Message, ex);
        }
    }
    

    Credits go to pfemiani, Li Chen, and someone I can't remember who putting it together in a code project's comment. Please note that pfemiani's answer does not work for me, yet combining it with Li Chen's post does.

  2. Make sure ASP .NET state service is running. It is where session data would be saved now.



回答3:

Sharing session between two asp.net web applications

Please refer below URL

http://www.freshcodehub.com/Article/48/sharing-session-between-two-aspnet-web-applications