If you have landed on this blog post, good chances are you are having issues with cookies of your web application which are being blocked by recent browser versions. Our case was no different.

We have an enterprise web application built on .Net which is deployed on a large scale across multiple clients and server configurations. Some of those clients had our application running off .Net 4.5.2. The client now wanted portions of the web application to be hosted in other public facing web assets of theirs in an iframe.

Our web app already supported third-party integrations (including SSO with common CMSes like WordPress, Drupal, and SharePoint etc) and being hosted in an iframe wasn’t supposed to be that difficult of a task. However the first attempt at the same where we tried to insert our web application in an iframe on a page of the WordPress site of the client failed spectacularly. The application wasn’t being allowed to set cookies it needed after successful SSO with the WordPress site. It is pertinent (and probably obviously assumed) to mention here that the authority of the web application (i.e. the .ASP.NET application) was different from the WordPress site (the top-level domains were different).

The same was expected now with browsers changing the default behaviour of SameSite cookies to Lax. I am not going to write much on the aspects of SameSite cookies and how the browser’s behavioural change has impacted web applications as the same is already documented well online (e.g. here and here).

Recent versions of .Net allow SameSite attribute of an HttpCookie to be manipulated programmatically as well as via configuration. The Secure attribute has always been available, so that was no problem. However the SameSite attribute was introduced in .Net 4.7.2 only. And the client did not immediately want to upgrade .Net version on their servers in their production web farm without going through the entire cycle of dev and staging servers which could have potentially taken atleast 3+ months as per their protocols.

So we were tasked to find a way to make SameSite cookies work in .Net 4.5.2 without needing an upgrade of .Net versions on the production servers.

I will share the solution first and then go into specifics of how we made it work. The following event handler placed in Global.asax.cs of your web application would ensure the application adheres to SameSite=None and Secure cookie restrictions needed by modern browsers when an application from a different authority is hosted in an iframe:

protected void Application_PreSendRequestHeaders ()
{
	var httpContext = HttpContext.Current;
	if (httpContext != null)
	{
		var cookieValueSuffix = "; Secure; SameSite=none";

		var cookies = httpContext.Response.Cookies;
		for (var i = 0; i < cookies.Count; i++)
		{
			var cookie = cookies[i];
			cookie.Value += cookieValueSuffix;
		}
	}
}

Basically we hook into the Application_PreSendRequestHeaders event of the HttpApplication object. This event is raised just before the cookies set in the current HttpRequest are about to be sent to the browser in the response headers. For each out-going cookie, we simply tag on Secure; SameSite=none attributes to the cookie. And voila, it makes the browsers super-happy (not to mention the client too 🙂 ).

There are a couple of gotchas though you should be aware of:

  1. Your web application should be running over HTTPS. Just adding the Secure attribute to the cookie won’t work, you need to ensure the web application is running over HTTPS.
  2. Browser (atleast Chrome) in incognito/private browsing (or whatever they call it) mode by default always block third-party cookies now (including from iframes). Your users would need to manually allow third-party cookies in private browsing/incognito browsing sessions.
    Here are the steps to do the same in Chrome:
    1. After users have opened your Website (the WordPress website page containing the iframe of the web application), they will see a crossed eye in the right-side of the address bar:

    2. Clicking the icon would pop-up this inline-dialog:

    3. Users need to click “Site not working” link which brings them to the following inline-dialog:

    4. Clicking the “Allow cookies” button should make Chrome automatically refresh the current web page and enable the iframe to set cookies.

A wise-dev once said: Every problem comes with a way to hack into it 😉