Cross-Domain Cookie with Legacy Applications

April 18th, 2016

Writing modern web applications is easy, but what happens when you need to interface with a legacy application and cookies are required? Today, I explain the gotchas with cross-domain applications.

Once you create your first ASP.NET MVC application, it's a great feeling.

You've created something out of nothing!

Creating a new application is easy.

However, integrating a brand new ASP.NET MVC website with a legacy website can be a challenge.

Our said challenge was an older WebForms application using ASP.NET 2.0 and we wanted (no, needed) to give the application a face lift, but it's not recommended that we rewrite the monolith. It would take years for this to be rewritten.

So how can we fix up this "old and busted" WebForms monolith?

Branch by Abstraction

Martin Fowler mentioned a technique called Branch by Abstraction and seemed like a suitable way for us to proceed with this particular application.

The idea behind the technique is to move specific parts of the monolith over to the "new hotness" and slowly disconnect and dissolve the old feature in the monolith.

I understand one alternative is to use microservices to break apart the monolith, but this particular application presents a difficult way for us to decouple a large amount of untested, WebForm code.

Again, it's definitely a challenge.

Cross-Domain Headaches

As of this last week, I hit my head against the first problem.

The older WebForms application wasn't really an application, it was an ASP.NET WebSite. Not a "web application."

Since we had this older WebForms web site project, the team needed a way to cleanly add an ASP.NET MVC application.

The WebForms application uses the Microsoft Membership and requires a cookie passed across the application.

But we're building a new ASP.NET MVC application and cookies don't travel across domains.

So how do you pass those credentials from an MVC application over to the older application without adding any additional code to the older WebForms app?

The solution we came up with is to create the application on a subdomain so the cookie works across domains.

This solved the issue of our applications working together seamlessly.

Now...for the gotchas

After implementing a subdomain for my local dev box, I was off and running.

I had the following domains working on my system for testing.

website1.localhost.com:888
website2.localhost.com:888

Fast-forward to Friday last week.

After a number of StackOverflow posts, here are the three things I learned over the week.

1. MachineKey

Make sure you have the machinekey element in your <system.web> section of your web.config.

  <machineKey validationKey="yourKeyHere" decryptionKey="yourOtherKeyHere"
                validation="SHA1" compatibilityMode="Framework20SP2" />

The ValidationKey and DecryptionKey has to be the same in both of your applications' web.configs.

NOTE: The missing piece to make the cross-domain membership work with the older WebForms was the compatibilityMode attribute. Once that attribute was added, the cookie persisted across the domain.

2. Add the enableCrossAppRedirects attribute to your Forms Element

In your system.web section, add an authentication element with forms.

  <forms loginUrl="yourLoginUrl"
             name=".MYFORMSAUTHNAME"
             timeout="30" cookieless="UseCookies"
             domain=".localhost.com"
             enableCrossAppRedirects="true" />

One of the gotchas I experienced was the enableCrossAppRedirects="true" (obviously).

If you don't have this attribute, it won't redirect properly.

3. Lastly, add the domain

The domain attribute is also a critical component.

  <forms loginUrl="yourLoginUrl"
               name=".MYFORMSAUTHNAME"
               timeout="30" cookieless="UseCookies"
               domain=".localhost.com"
               enableCrossAppRedirects="true" />

The leading period is required when using subdomains so the cookie can travel between the applications. 

Conclusion

The amount of effort it took for this to be implemented was contingent upon typing in the right Google keywords to find the solution.

I wanted to post this particular story of using cross-domain cookies with legacy applications so no one has this same issue in the future.

After implementing everything described above, I can now log into an ASP.NET MVC and automatically go to the primary screen in the WebForms application.

UPDATE: I also want to thank the parties involved with this question on StackOverflow. This was one of those well-placed keyword searches in Google to find the right answer.

Was this a good way to enhance this application? Would it have been better to rewrite the whole WebForms applicatiion? Post you thoughts below.