(CORS C# ASP.NET Core) Practical Verification of Credential Cookies

In this tutorial, we have two applications - the first is an ASPNET Core application that implements a CORS policy to accept cookies from the second application. The second application makes a javascript request to the first application and sends a cookie. The first application then reads the cookie and echoes back the contents of that cookie, which are presented by the browser through a javascript alert box. The source code of both the projects is provided in the attached downloads.
(Rev. 19-Mar-2024)

Categories | About |     |  

Parveen,

The Server side Website

First of all open the server-side website project. We have already discussed this project in the previous tutorial. You might want to go back to the previous tutorial for a continuity. Locate the program.cs file and double-click to open it!

We have specified a default cross-origin policy that white-lists a localhost port 7277, which shall be the port of our client application. The policy sets AllowCredentials so that the application permits cross-site cookies.

using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder();

builder.Services.AddRazorPages();

builder.Services.AddCors(options =>
{
  options.AddDefaultPolicy(policy =>
    {
      policy.WithOrigins("https://localhost:7277")
            .AllowCredentials();
    }
  );
});

var app = builder.Build();

app.UseCors();

app.MapRazorPages();

// to create a test cookie 
app.MapGet("/mkcookie", ([FromQuery]String email, HttpContext ctx) =>
{
  ctx.Response.Cookies.Append(
    "user", 
    email, 
    new CookieOptions() { Expires = DateTime.Now.AddDays(20) }
  );

  return Results.Ok("cookie created!");
});

// this api will be called from 
// cross-origin javascript 
app.MapGet("/call", (HttpContext ctx) =>
{
  var ck = ctx.Request.Cookies.FirstOrDefault(x => x.Key == "user");

  return Results.Ok($"Cookie received {ck.Key} - {ck.Value}");

});

app.Run();
  
  
  

Then we have added a web api that creates a cookie and stores the incoming email address in this cookie. This web api will be called from the client application to create a test cookie of name "user".

After this we have a web api that receives the cross-origin cookie. It will be called through javascript from the client application. This code extracts the cookie of name "user" and echoes it back to the client application.

Video Explanation (see it happen!)

Please watch the following youtube video:

The Website that sends a CORS Request

Next open the solution explorer of the third-party website project. This is also an ASPNET Core project. Locate the launchSettings.cshtml file and open it. The localhost port of this project is 7277.

// launchSettings.json file of the calling app 

{
  "profiles": {

    "MyRazorApp": {

      "commandName": "Project",

      "launchBrowser": true,

      "launchUrl": "https://localhost:7277",

      "applicationUrl": "https://localhost:7277"

    }
  }
}

Next locate the Index.cshtml home page file. Double click and open it! Let's examine the markup for this file.

We need a cookie before we can send it. In real websites, such a cookie is created during the login process. But since we do not want to complicate matters, we shall use a common trick to create a cookie.

A hidden image tag makes a request to the /mkcookie web API and sends an email as a parameter. The web API is on the server side on port 7276, as already explained, and it causes a cookie to be created.

This trick is not recommended in real projects because the call takes place whenever the page is loaded, which might be in-efficient. We have done it only for the sake of a tutorial.


// index.cshtml file 

@page

<h1>Welcome Home!</h1>

<!-- hidden img to create a credentials cookie -->

<img src="https://localhost:7276/mkcookie?user=abc@gmail.com"
     style="display:none" />

<a id="myButton" href="javascript:null">Click to Send Ajax Request</a>

<script type="text/javascript">

  myButton.onclick = function() {

      fetch("https://localhost:7276/call", {credentials: "include"})
      .then((response) => response.json())
      .then((data) => alert(data))
      .catch((error) => { alert('Error:' + error); });

  }

</script>

After that we have a button to send an ajax fetch request to the server.

The fetch request sets the credentials property to "include". This is a compulsory requirement if cookies have to be sent cross-origin. The json response is shown in an alert box.

Run the Projects

Let's test the whole system now.

First run the server application and allow the home page to open.

After this run the client application and allow the home page to open. The hidden img tag makes a call to the /mkcookie API and causes a cookie to be created. Use the chrome helper to verify the existence of this cookie and the contents.

Next click the "Click to Send Ajax Request" button and we verify that the call to /call API succeeds and the same cookie is shown in an alert box as expected.

Run an experiment now

Let's now run an experiment. Modify the server application and remove the AllowCredentials call. Run the server application again.

And again run the client application, and click the "Click to Send Ajax Request" button. We verify that the request fails this time because the server did not send the Access-Control-Allow-Credentials header.

Now CORS credentials workflow should be clear. Thanks!


This Blog Post/Article "(CORS C# ASP.NET Core) Practical Verification of Credential Cookies" by Parveen is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License.