Hello, in this article, we will API Key authorization on ASP.NET Core Web API with middleware and attribute. We will create an ASP.NET Core Web API project named ApiKeyAuthentication.
Using Middleware
We add a Middlewares folder to the project and add a class called ApiKeyMiddleware.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
namespace ApiKeyAuthentication.Middlewares
{
public class ApiKeyMiddleware
{
private readonly RequestDelegate _requestDelegate;
private const string ApiKey = "X-API-KEY";
public ApiKeyMiddleware(RequestDelegate requestDelegate)
{
_requestDelegate = requestDelegate;
}
public async Task Invoke(HttpContext context)
{
if (!context.Request.Headers.TryGetValue(ApiKey, out var apiKeyVal))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Api Key not found!");
}
var appSettings = context.RequestServices.GetRequiredService<IConfiguration>();
var apiKey = appSettings.GetValue<string>(ApiKey);
if (!apiKey.Equals(apiKeyVal))
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("Unauthorized client");
}
await _requestDelegate(context);
}
}
}
ApiKeyMiddleware.cs
When we examine the code, we check the X-API-KEY in HttpContext Headers. If there is a value, we compare it with the X-API-KEY value in appsettings. If the value is true, we continue the process.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using ApiKeyAuthentication.Middlewares;
using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(x =>
{
x.AddSecurityDefinition("X-API-KEY",new OpenApiSecurityScheme
{
Name = "X-API-KEY",
Type = SecuritySchemeType.ApiKey,
Scheme = "ApiKeyScheme",
In = ParameterLocation.Header,
Description = "ApiKey must appear in header"
});
x.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "X-API-KEY"
},
In = ParameterLocation.Header
},
new string[]{}
}
});
});
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
//app.UseMiddleware<ApiKeyMiddleware>();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Program.cs
Here we should pay attention to the swagger configuration. If we want to send api key with Swagger, we configure AddSecurityDefinition and AddSecurityRequirement in the AddSwaggerGen method.
1
2
3
4
5
6
7
8
9
10
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*",
"X-API-KEY": "QXBpS2V5TWlkZGxld2FyZQ=="
}
appsettings.json
Using Atrribute
We create a folder named Attributes and create a class called ApiKey Attribute.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
using Microsoft.AspNetCore.Mvc.Filters;
namespace ApiKeyAuthentication.Attributes
{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ApiKeyAttribute : Attribute, IAsyncActionFilter
{
private const string ApiKey = "X-API-KEY";
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
if (!context.HttpContext.Request.Headers.TryGetValue(ApiKey, out var apiKeyVal))
{
context.HttpContext.Response.StatusCode = 401;
await context.HttpContext.Response.WriteAsync("Api Key not found!");
}
var appSettings = context.HttpContext.RequestServices.GetRequiredService<IConfiguration>();
var apiKey = appSettings.GetValue<string>(ApiKey);
if (!apiKey.Equals(apiKeyVal))
{
context.HttpContext.Response.StatusCode = 401;
await context.HttpContext.Response.WriteAsync("Unauthorized client");
}
}
}
}
ApiKeyAttribute.cs
As we did in the Middleware class, we continue the process after reaching the api key value in the HttpContext Header and verifying it.[AttributeUsage] is the part we should pay attention to here. With this attribute, we set in which parts of the class our class can be used.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
using ApiKeyAuthentication.Attributes;
using Microsoft.AspNetCore.Mvc;
namespace ApiKeyAuthentication.Controllers
{
[ApiController]
[Route("[controller]")]
[ApiKey]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}
}
WeatherForecastController.cs
You can download the project here. Please let me know if there are typos in my post.