Search code examples
c#asp.netcookiesgeneric-handler

Cookie created in Generic Handler visible when browsing directly to the handler but not if the handler is called from an aspx page (c#/.NET)


I have a generic handler (cookiecutter.ashx) on a cloud server that sets a cookie. I need to read this cookie from my local production server. The cloud server uses a subdomain of the domain on the production server (for example the handler is at cloudserver.example.com and the production server is www.example.com). The domain of the cookie is set to ".example.com". If I browse directly to cookiecutter.ashx in a browser, the cookie gets created and is visible in the browser cookie collection (using Chrome DevTools) and I can read the cookie from www.example.com. However, if I make an ajax call(JQuery) to the handler from www.example.com, the cookie can't be read from www.example.com and does not appear in the browser cookie collection.

Why is the cookie only readable from www.example.com if I browse directly to the handler? Is there any way to get the same result when calling the handler using ajax?


Solution

  • I finally have it working.

    When it wasn't working, I had the following HTTP Response Headers on the server where the cookie is created:

    Access-Control-Allow-Origin = *, Access-Control-Allow-Methods = GET, POST, OPTIONS
    

    The solution was:

    1. Add the following HTTP Response Header:

      Access-Control-Allow-Credentials = true
      
    2. Change Access-Control-Allow-Origin to https://www.example.com (you can't use a wildcard when implementing the Access-Control-Allow-Credentials header; you have to specify the origin)

    3. Add the following parameter to the JQuery AJAX call to the handler:

      xhrFields: {withCredentials: true}
      
    4. Add the Secure attribute to the cookie when it is created (theCookie.Secure=true;)

    5. Add the following to the system.web section of the web.config file for the project that creates the cookie:

      <httpCookies sameSite="None" />

    I should also mention that you must be using the same machine key for the project that creates the cookie and the project(s) that read the cookie.

    Finally, if the cookie is to be read by a mixture of .NET frameworks, you will also need to add a CompatabilityMode to the machine key. In my case all frameworks were .NET 2.0 or greater so I used: compatibilityMode="Framework20SP2"

    More on compatabilityMode here: https://learn.microsoft.com/en-us/dotnet/api/system.web.configuration.machinekeysection.compatibilitymode?view=netframework-4.8.