Share Session between two web sites using asp.net and state server

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.

Leave a Comment