Question

I'm trying to set up forms authentication across multiple servers and subdomains. I have static machine keys set up for each application like so:

<system.web>
    <machineKey validationKey="574...7A7" 
                decryptionKey="2C3...A0D" 
                validation="HMACSHA256" 
                decryption="AES" />
</system.web>

...and my forms authentication is configured the same for each application:

<forms loginUrl="/login" timeout="2880" defaultUrl="/" path="/" name=".SHAREDAUTH" domain="domain.com" protection="All" />

I've also tried prefixing my domain with a period as I've seen some people suggest, but that didn't work either.

This works fine on my local machine with separate sites set up in IIS for each subdomain. It also works fine on our dev server, where all sites still reside on a single machine. When I deploy to our staging environment, however, the cross-domain authentication stops working. In that environment, I have the primary site (where login occurs) running on a single server, and the secondary site (where my authentication should persist) running on two load-balanced servers. All are running under IIS 7 on either Windows 7 (local) or Server 2008 R2 (dev and staging).

I verified that the machine keys are the same by encoding a string on the primary site with MachineKey.Encode and decoding the result on the secondary server with MachineKey.Decode. I also verified that the .SHAREDAUTH cookie is passed to the second application in the request, both by checking the request headers as reported by Firefox and Chrome, and hooking the debugger to Application_BeginRequest and Application_AuthenticateRequest. I can see the cookie during Application_BeginRequest execution, but it's gone when Application_AuthenticateRequest is called. From what I can gather, that seems to mean that the deserialization of the authentication ticket failed, but I can't figure out why that could be happening in the multi-server environment, but not the single server environment, aside from different machine keys, which I already confirmed was not the case.

I also have a custom MembershipProvider and RoleProvider set up, and those work fine independently on each site.

What am I missing?

Was it helpful?

Solution

So, after a long slog I discovered MS security bulletin MS11-100, which patches an elevation of privilege vulnerability in forms authentication. Unfortunately, the patch is not backwards compatible. It was applied to our load balanced servers, but not to the server hosting the application that created the initial log-in, which meant that the balanced servers couldn't deserialize the authentication ticket written by the app server.

Per the MS deployment guidance article, if you find yourself in this situation, you can add

<add key="aspnet:UseLegacyFormsAuthenticationTicketCompatibility" value="true" />

to the appSettings section in the web.config for applications on the machines with the patch installed (or to the machine-level config). Or, better yet, make sure you're hosting management company applies the patch to all of your servers at the same time...

OTHER TIPS

For me it works adding this keys in the appsettings:

    <add key="aspnet:UseLegacyEncryption" value="true" />
    <add key="aspnet:UseLegacyFormsAuthenticationTicketCompatibility" value="true" />
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top