Home > other >  Custom API Key Authentication method in .net core not working on controller
Custom API Key Authentication method in .net core not working on controller

Time:08-14

I am trying to create an ASP.NET Core Web API for the first time. I am trying to use API key based authentication to call the methods, where users need to pass the authentication key in the HTTP header.

Issue is that API method called without any authentication. Like when I try to call http://localhost:50797/api/Order, it is called without any authentication. But when I call http://localhost:50797/, it requires authentication.

My complete test project on Github for your review and advice, Deeply thanks for your suggestions.

As per URL I created Folder Middleware and code as per below.

public class ApiKeyMiddleware
{
    private readonly RequestDelegate _next;
    private
    const string APIKEY = "XApiKey";

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

    public async Task InvokeAsync(HttpContext context)
    {
        if (!context.Request.Headers.TryGetValue(APIKEY, out
                var extractedApiKey))
        {
            context.Response.StatusCode = 401;
            await context.Response.WriteAsync("Api Key was not provided ");
            return;
        }

        var appSettings = context.RequestServices.GetRequiredService<IConfiguration>();
        var apiKey = appSettings.GetValue<string>(APIKEY);          

        if (!apiKey.Equals(extractedApiKey))
        {
            context.Response.StatusCode = 401;
            await context.Response.WriteAsync("Unauthorized client");
            return;
        }
        await _next(context);
    }
}

Startup.cs changes as per below

public class Startup
{
    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public IConfiguration Configuration { get; }

    // This method gets called by the runtime. Use this method to add services to the container.
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllers();
       //services.AddSingleton<IPlaceInfoService, PlaceInfoService>();
        services.AddSwaggerGen(options =>
        {
            options.SwaggerDoc("v2", new Microsoft.OpenApi.Models.OpenApiInfo
            {
                Title = "IDLS  API",
                Version = "v2",
                Description = " Service",
            });

            options.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme
            {
                Description = "ApiKey must appear in header",
                Type = SecuritySchemeType.ApiKey,
                Name = "XApiKey",
                In = ParameterLocation.Header,
                Scheme = "ApiKeyScheme"
            });
            var key = new OpenApiSecurityScheme()
            {
                Reference = new OpenApiReference
                {
                    Type = ReferenceType.SecurityScheme,
                    Id = "ApiKey"
                },
                In = ParameterLocation.Header
            };
            var requirement = new OpenApiSecurityRequirement
                {
                         { key, new List<string>() }
                };
            options.AddSecurityRequirement(requirement);
        });
    }

    // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseSwagger();
            //app.UseSwaggerUI();
        }

        app.UseRouting();
        app.UseAuthorization();
        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllers();
        });            
        app.UseSwagger();
        app.UseSwaggerUI(options => options.SwaggerEndpoint("/swagger/v2/swagger.json", "Order Services"));
        app.UseMiddleware<ApiKeyMiddleware>();
    }
}

OrderController.cs

public class OrderController : ControllerBase
    {
        private readonly IOrderService _OrderService;

        [HttpPost]
        public string OrderDetails()
        {
            return "HHHHH";
        }
    }

CodePudding user response:

Move app.UseMiddleware line before app.UseRouting() method and middleware will be called for all API calls.

if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
            app.UseSwagger();
            //app.UseSwaggerUI();
        }

        app.UseMiddleware<ApiKeyMiddleware>();

        app.UseRouting();
        app.UseAuthorization();
  • Related