Cross-Domain Forms Authentication with ASP.NET
Posted by Dylan Beattie on 30 March 2012 • permalinkI'm looking into splitting bits of a web application across multiple domains, so that - for example - all logins, password changes, etc. are handled at http://security.example.com/, payments and order history are handled at http://accounts.example.com/ and so on. Just to keep things interesting, some of these apps are in .NET 2.0 and some are greenfield apps we'll be building in .NET 4.0.
Good news is - it's completely possible. And with IIS 7, it's apparently even possible to secure static pages, classic ASP and other non-.NET pages using the same authentication mechanism.
Step 1: Make sure your machineKey values are identical
Each application that's going to participate in cross-domain authentication needs an identical machineKey element - this defines the encryption keys that are used to encrypt and decrypt the .ASPXAUTH cookie that contains the authenticated user data.
In my solution, I generated a machineKey using http://aspnetresources.com/tools/machineKey and then added this to the web.config files for each application individually - it goes under <system.web> like:
<system.web>
<machineKey validationKey="yada yada yada" decryptionKey="yada yada yada" validation="SHA1" decryption="AES" />
</system.web>
In theory, you could also define this in your machine.config or machine-level web.config file - remembering that you may have up to four of these (x86 .NET 20, x86 .NET 4.0, x64 .NET 2.0 and x64 .NET 4.0) - but I haven't tested this approach.
Step 2: Configure your FormsAuthentication attributes
Add this to the <system.web> section of the applications that are going to participate in cross-domain authentication:
<authentication mode="Forms">
<forms loginUrl="https://security.example.com/login" timeout="2880" domain=".example.com" path="/" />
</authentication>
Key points to note here:
- The loginUrl is an absolute reference to the site that hosts your security app - so if you try to view a secure page, it'll redirect you to this website to log in.
- The cookie domain is set to ".example.com" = notice the leading dot. That's important - it means the same cookie will be sent to example.com, something.example.com, another.url.at.example.com, and so on.
You'll need to make sure you're calling FormsAuthentication.SetAuthCookie(username) on your login server, but once that's done, you should be able to retrieve HttpContext.Current.User.Identity.Name from anywhere on any participating server. It is still up to you to verify that the username is valid and authorized - but this should save you a bit of plumbing when it comes to getting things working.