Added an option to require a key for access to API.
This commit is contained in:
parent
e7eef31b7e
commit
7c869a63cf
64
Proculite.GpioRest/Middlewares/SecurityMiddleware.cs
Normal file
64
Proculite.GpioRest/Middlewares/SecurityMiddleware.cs
Normal file
|
|
@ -0,0 +1,64 @@
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Proculite.GpioRest.Middlewares
|
||||||
|
{
|
||||||
|
public class SecurityMiddleware
|
||||||
|
{
|
||||||
|
private readonly RequestDelegate _next;
|
||||||
|
private readonly IConfiguration _configuration;
|
||||||
|
private readonly ILogger<SecurityMiddleware> _logger;
|
||||||
|
|
||||||
|
public SecurityMiddleware(
|
||||||
|
RequestDelegate next,
|
||||||
|
IConfiguration configuration,
|
||||||
|
ILogger<SecurityMiddleware> logger
|
||||||
|
)
|
||||||
|
{
|
||||||
|
_logger = logger;
|
||||||
|
_configuration = configuration;
|
||||||
|
_next = next;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext context)
|
||||||
|
{
|
||||||
|
IConfigurationSection keySection = _configuration.GetSection("Key");
|
||||||
|
if (!keySection.Exists())
|
||||||
|
{
|
||||||
|
_logger.LogWarning(
|
||||||
|
"Configuration does not contain a key. Running in insecure mode."
|
||||||
|
);
|
||||||
|
await _next(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string? accessKey = keySection.Get<string>();
|
||||||
|
if (accessKey is null)
|
||||||
|
{
|
||||||
|
_logger.LogError("Key is expected but is not set.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
string? requestKey = context.Request.Headers.Authorization.FirstOrDefault();
|
||||||
|
|
||||||
|
if (requestKey == accessKey)
|
||||||
|
{
|
||||||
|
await _next(context);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.Response.StatusCode = StatusCodes.Status401Unauthorized;
|
||||||
|
context.Response.ContentType = "text/plain; charset=utf-8";
|
||||||
|
byte[] messageBytes = Encoding.UTF8.GetBytes("Invalid key is used. Access denied.");
|
||||||
|
context.Response.ContentLength = messageBytes.Length;
|
||||||
|
await context.Response.Body.WriteAsync(messageBytes);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class SecurityMiddlewareExtensions
|
||||||
|
{
|
||||||
|
public static IApplicationBuilder UseSecurity(this IApplicationBuilder builder)
|
||||||
|
{
|
||||||
|
return builder.UseMiddleware<SecurityMiddleware>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,3 +1,4 @@
|
||||||
|
using Proculite.GpioRest.Middlewares;
|
||||||
using Proculite.GpioRest.Services;
|
using Proculite.GpioRest.Services;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
@ -12,6 +13,9 @@ builder.Services.AddSingleton<GpioService>();
|
||||||
|
|
||||||
var app = builder.Build();
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Custom security. Expects traffic to be secure (HTTPS).
|
||||||
|
app.UseSecurity();
|
||||||
|
|
||||||
app.MapControllers();
|
app.MapControllers();
|
||||||
app.UseSwagger();
|
app.UseSwagger();
|
||||||
app.UseSwaggerUI();
|
app.UseSwaggerUI();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue