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:
- 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.
- 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:- 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:
- Clicking the icon would pop-up this inline-dialog:
- Users need to click “Site not working” link which brings them to the following inline-dialog:
- Clicking the “Allow cookies” button should make Chrome automatically refresh the current web page and enable the iframe to set cookies.
- 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:
A wise-dev once said: Every problem comes with a way to hack into it 😉
Hello
Thanks a lot for this article.
I work on Mvc.net 4 website and I have problem with cookie il Iframe.
I had Application_PreSendRequestHeaders and it’s ok.
Hi, I am not sure I understand your question completely. Can you please elaborate?
The above fix did not work for a Safari browser
Can you please advise?
Hi Simanta, this is a server-side fix. It has nothing to do with a browser. Check in Fiddler or Postman please if the server is returning cookie with the correct SameSite attributes. Lemme know what you see there in Response cookies.
Is the implementation same for MVC applications also or only for webforms
Well Sumanth, the code goes in Global.asax.cs. Which is common across ASP.NET, whether web forms or MVC. So the implementation is going to remain the same for MVC applications also.
Thankyou I appreciate your help
Sure Sumanth 🙂