Blog

Filter posts by Category Or Tag of the Blog section!

Implementing custom element based authentication in asp.net core

Friday, 24 April 2020

Recently I wanted to create a custom authentication, to authorize by ApiKey and ApiSecret in the header. To create such a middleware to affect the entire services of the system I created the following: 



 

using System;

using System.Linq;

using System.Text;

using System.Threading.Tasks;

using Microsoft.AspNetCore.Http;

using Microsoft.Extensions.Configuration;

using Microsoft.Extensions.Logging;



public class ApiKeyMiddleware

{

    private readonly RequestDelegate _next;

    private readonly IConfiguration _config;

    private readonly ILogger _logger;



    public ApiKeyMiddleware(RequestDelegate next, IConfiguration config, ILogger<ApiKeyMiddleware> logger)

    {

        _next = next;

        _config = config;

        _logger = logger;

    }



    public async Task InvokeAsync(HttpContext context)

    {

        if (!context.Request.Headers.ContainsKey("X-Api-Key") || !context.Request.Headers.ContainsKey("X-Api-Secret"))

        {

            _logger.LogWarning("Missing API key or secret.");

            context.Response.StatusCode = 401;

            await context.Response.WriteAsync("Unauthorized");

            return;

        }



        var apiKey = context.Request.Headers["X-Api-Key"].FirstOrDefault();

        var apiSecret = context.Request.Headers["X-Api-Secret"].FirstOrDefault();



        if (!IsAuthorized(apiKey, apiSecret))

        {

            _logger.LogWarning($"Invalid API key or secret: {apiKey}");

            context.Response.StatusCode = 401;

            await context.Response.WriteAsync("Unauthorized");

            return;

        }



        await _next(context);

    }



    private bool IsAuthorized(string apiKey, string apiSecret)

    {

        var storedApiKey = _config.GetValue<string>("ApiKey");

        var storedApiSecret = _config.GetValue<string>("ApiSecret");



        if (apiKey == storedApiKey && apiSecret == storedApiSecret)

        {

            return true;

        }



        return false;

    }

}

 

In the InvokeAsync method of this middleware, I check if the request headers contain the X-Api-Key and X-Api-Secret headers. If they are missing, I return a 401 Unauthorized response. If they are present, I check if the provided key and secret match the ones stored in the configuration. If they match, I continue with the request processing. If they don't match, I return a 401 Unauthorized response. Next, I added this middleware to the pipeline in the Configure method of Startup.cs:


 

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

{

    // ...



    app.UseMiddleware<ApiKeyMiddleware>();



    // ...

}


Finally, I added the ApiKey and ApiSecret configuration values to the appsettings.json file:


 

{

  "ApiKey": "your-api-key",

  "ApiSecret": "your-api-secret"

}

 

This was just a simple form of what I created for the project as it has more challenges. Hope it helps!

 

comments powered by Disqus