Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / ASP.NET / ASP.NET-Core

Cookie Logging In Middleware of ASP.NET Core Web API / MVC Application

5.00/5 (6 votes)
30 Jun 2021CPOL3 min read 10K  
About Cookie authentication events
In this tip, we will look into Cookie authentication events and how it allows subscribing to events raised during cookie authentication. We will see how to know the cookie and its values by subscribing to the cookie authentication events and what are the main parts of the cookie authentication events.

Introduction

Sometimes, we have to do logging on Cookies for debugging in development site or in the production site. We had a situation like that.

Background

In our big Web API that serves data to the Android client, we used authentication for that client and server communication. Authentication of app is based on uniquely generated Authentication token. It happens automatically whenever the login required. Once, we had an issue that was requested from our client that passed authentication for one request but failed for the next request that was raised immediately after the first request to the same URI. We haven't encountered that situation in any other apps. That error happened in one or two devices only over 200 devices.

Then we started debugging the session. First, we verified whether the login token is valid or not, that is valid, then we move to the next step of our process. Whatever we did on the business side always looked fine from any perspective. We had no idea what was going on. If at all that problem existed in API side, why did select one or two devices have problem, not all?

Finally, we landed on the debugging session of what we are getting as cookie because authentication is based on cookie only, right. If that submitted cookie is valid, then the problem is in the API side. If the cookie is not what we have given to them, then the problem is on the app side. To do this debug session, we started analyzing how to log the cookie. To know/log the cookie, we have to know the following details:

  • Cookie generated by the server on login
  • Cookie submitted by the client on each request

For this big question, ASP.NET Core provides best solutions. We took:

  • Cookie Authentication Events to know the generated cookie
  • Middleware to know the submitted cookie

Cookie Authentication Events

Allows subscribing to events raised during cookie authentication. By subscribing to the cookie authentication events, we can know the cookie and its values. Mainly, this cookie authentication event has the following events:

  • RedirectToAccessDenied
  • RedirectToLogin
  • RedirectToLogout
  • RedirectToReturnURL
  • SigningIn
  • SignedIn
  • SignedOut
  • ValidatePrincipal

We have used RedirectToAccessDenied, SignedIn, SigningIn events.

Finally Our CookieAuthenticationEvents class looks like this:

C#
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using System.Threading.Tasks;

namespace Web
{
    public class MyCookieAuthenticationEvents : CookieAuthenticationEvents
    {
        public override Task RedirectToAccessDenied
               (RedirectContext<CookieAuthenticationOptions> context)
        {
            //Logging the required details
            //Request Body has the client submitted cookie, if submitted 
            //Request available in the context. `context.HttpContext.Request`
            
            return base.RedirectToAccessDenied(context);
        }

        public override Task SigningIn(CookieSigningInContext context)
        {
            //Logging the required details
            
            return base.SigningIn(context);
        }

        public override Task SignedIn(CookieSignedInContext context)
        {            
            //Logging the required details
            //Generated new cookie information available here. In the request Body. 
            //Request available in the HttpContext. `context.HttpContext.Request`
            
            return base.SigningIn(context);
        }
    }
}

We have to mention this is the cookie authentication event listener somewhere, right. This is done in the place where we define cookie authentication schemes. In our approach, that is startup.cs class. This authentication configurations are done under the ConfigureServices section of startup.cs class. Somewhere in the startup class, we definitely used something like below:

C#
public void ConfigureServices(IServiceCollection services)
{
    ...
    
    services
        .AddAuthentication()
        .AddCookie("<Name Of the Authentication Scheme>", options => 
            { 
                ... 
            });
    ...
}

To mention the CookieAuthenticationEvents, we will make the following changes on the above code block:

C#
public void ConfigureServices(IServiceCollection services)
{
    ...
    
    services
        .AddAuthentication()
        .AddCookie("", options => 
            { 
                ...
                options.Events = 
                new MyCookieAuthenticationEvents(); // this is newly added line
            });
    ...
}

Now, this will tell us what cookie is generated and related details.

Cookie Logging Middleware

The second big portion of our analysis is logging the cookie. To do this, we have decided to use middleware. Our cookie logging middleware looks like:

C#
using System.Threading.Tasks;

namespace Web
{   
    public class MyCookieLogMiddleware
    {
        private readonly RequestDelegate _next;

        public MyCookieLogMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task Invoke(HttpContext context)
        {
            await _next.Invoke(context);
            
            //Logging the required details
            //Submitted Cookies available in the request. `context.Request.Cookies`
            //Generated or response cookies available in the response header. 
            // `context.Response.Headers["Set-Cookie"]`
        )                    
	}
}

To work this middleware, we have to add it to the ApplicationBuilder of our application, which is also possible via the startup.cs class. This Startup.cs class has the Configure method. This can done easily by having middleware extension.

C#
public static class MiddlewareExtensions
{
    public static IApplicationBuilder UseMyCookieLogMiddleware
                                    (this IApplicationBuilder instance)
    {
        return instance.UseMiddleware<mycookielogmiddleware>();
    }
}

Finally, in startup.cs:

C#
public void Configure(IApplicationBuilder app, 
                      IHostingEnvironment env, ILoggerFactory loggerFactory)
{
    ...
	app.UseAuthentication();
	app.UseCookieLogMiddleware(); //this is the line we have to include.
    ...
    app.UseMvc();
}

This cookie logging middleware should be presented between UseAuthentication and UseMvc middleware definitions. Done! Now try logging cookie.

Precautions

Authentication cookies are more sensitive information. If anyone gets this information, then we will be in trouble, so please be aware of this. Do not enable it permanently and also do not log/write the cookie in any public place which is accessed by a third person.

Conclusion

This tip may help someone who looking for the solution to log cookies generated by server and sumitted by the client applications. Thank you for reading!

History

  • 30th June, 2021: Initial version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)