Google & Microsoft Token Validation Middleware in ASP.NET Applications

  I have been working on a web app that allows 3rd party login. I had to validate the token that existed in the authorization header of each request hitting my backend services.

The frontend team handled the 3rd party login and obtained a token from one of two providers: Google or Microsoft.

Middleware

The first step I decided to create middleware that intercepts all calls to my applications to validate the token before taking any further steps.

And because ASP.NET Core calls middlewares in order just like a pipeline so it's very important to register this middleware before any other middleware you would like to register, so as not to do any unnecessary processing of requests which are yet to be authenticated.

So basically, I created a class inside my API project under a folder named TokenHandling.

And right away always remember to register your middleware/services because sometimes you get caught up in applying your solution that miss the step where you register your new service in your application so just add the following line in your startup.cs program.cs file.

app.UseMiddleware<TokenValidationMiddleware>();

Basically, this is how your middleware should look like after you add it and add the necessary InvokeAsync function that gets invoked automatically and also add the RequestDelegate parameter that gets injected too.

    public class TokenValidationMiddleware(RequestDelegate requestDelegate)
    {
        public async Task InvokeAsync(HttpContext context)
        {
            await requestDelegate(context);
        }
    }

Token Validation

The next step we need to extract the token from the Authorization header, so you need to add a couple of  lines to your InvokeAsync function in your middleware so that it would look as follows.

        public async Task InvokeAsync(HttpContext context)

        {
            var token = context.Request.Headers[HeaderNames.Authorization].ToString().Replace($"{JwtBearerDefaults.AuthenticationScheme} ", string.Empty);
            await ValidateTokenAsync(token);
            await requestDelegate(context);
        }

Where ValidateTokenAsync is function where you apply one of the following validations on the token whether you choose to validate it as a Google or a Microsoft token or both by using switch or a condition based on the value of an additional header.

Google Authentication

Using Google.Apis.Auth nuget package you can validate your token in only one line so your ValidateTokenAsync function can look as follows.

        public async Task<bool> ValidateTokenAsync(string token)

        {

            await GoogleJsonWebSignature.ValidateAsync(token);

            return true;

        }

Microsoft Authentication

To validate a Microsoft token, change the ValidateTokenAsync function to the following:

        public async Task<bool> ValidateTokenAsync(string token)

        {

            var stsDiscoveryEndpoint = "https://login.microsoftonline.com/common/v2.0/.well-known/openid-configuration";


            ConfigurationManager<OpenIdConnectConfiguration> configManager = new(stsDiscoveryEndpoint, new OpenIdConnectConfigurationRetriever());


            OpenIdConnectConfiguration config = configManager.GetConfigurationAsync().Result;


            var validationParams = new TokenValidationParameters

            {

                IssuerSigningKeys = config.SigningKeys,

                ValidateAudience = false,

                ValidateIssuer = false

            };


            var microsoftTokenHandler = new JwtSecurityTokenHandler();


            microsoftTokenHandler.ValidateToken(token, validationParams, out SecurityToken jwt);


            return true;

        }

Perfect! Now you're all set to validate the token provided to you.

Comments

Popular posts

Publish and Consume Messages Using RabbitMQ as a Message Broker in 4 Simple Steps 🐰

Real Life Case Study: Synchronous Inter-Service Communication in Distributed Systems