123 lines
6.2 KiB
C#
123 lines
6.2 KiB
C#
using LCU.Library.Internal.ApiSecurity.Constants;
|
|
using Microsoft.AspNetCore.Http;
|
|
using LCU.Library.Internal.ApiSecurity.Enums;
|
|
using LCU.Library.Internal.ApiSecurity.Models;
|
|
using Microsoft.AspNetCore.Http.Extensions;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace LCU.Library.Internal.ApiSecurity.Middleware
|
|
{
|
|
public class ApiKeyMiddleware
|
|
{
|
|
private readonly ApiSecurityConfiguration _apiSecurityConfiguration;
|
|
private readonly ILogger _logger;
|
|
private readonly RequestDelegate _next;
|
|
|
|
public ApiKeyMiddleware(RequestDelegate next, ApiSecurityConfiguration apiSecurityConfiguration, ILoggerFactory loggerFactory)
|
|
{
|
|
_next = next;
|
|
_apiSecurityConfiguration = apiSecurityConfiguration;
|
|
_logger = loggerFactory.CreateLogger(GetType().Name);
|
|
}
|
|
|
|
public async Task InvokeAsync(HttpContext context)
|
|
{
|
|
var displayUrl = context.Request.GetDisplayUrl();
|
|
if (_apiSecurityConfiguration.ExternalApiKeySet.Any())
|
|
{
|
|
if (!context.Request.Headers.TryGetValue(HeaderKeys.ApiKey, out var extractedApiKey))
|
|
{
|
|
switch (_apiSecurityConfiguration.ApiKeyAuthenticationFailureBehavior)
|
|
{
|
|
case ApiKeyAuthenticationFailureBehavior.Warn:
|
|
_logger.LogWarning(AuthMessages.NotProvidedMessage(HeaderKeys.ApiKey));
|
|
break;
|
|
case ApiKeyAuthenticationFailureBehavior.Error:
|
|
_logger.LogError(AuthMessages.NotProvidedMessage(HeaderKeys.ApiKey));
|
|
context.Response.StatusCode = 401;
|
|
await context.Response.WriteAsync(AuthMessages.NotProvidedMessage(HeaderKeys.ApiKey));
|
|
return;
|
|
default:
|
|
throw new Exception("Invalid ApiKeyAuthenticationFailureBehavior Value");
|
|
}
|
|
}
|
|
|
|
if (!context.Request.Headers.TryGetValue(HeaderKeys.Client, out var extractedClient))
|
|
{
|
|
switch (_apiSecurityConfiguration.ApiKeyAuthenticationFailureBehavior)
|
|
{
|
|
case ApiKeyAuthenticationFailureBehavior.Warn:
|
|
_logger.LogWarning(AuthMessages.NotProvidedMessage(HeaderKeys.Client));
|
|
break;
|
|
case ApiKeyAuthenticationFailureBehavior.Error:
|
|
_logger.LogError(AuthMessages.NotProvidedMessage(HeaderKeys.Client));
|
|
context.Response.StatusCode = 401;
|
|
await context.Response.WriteAsync(AuthMessages.NotProvidedMessage(HeaderKeys.Client));
|
|
return;
|
|
default:
|
|
throw new Exception("Invalid ApiKeyAuthenticationFailureBehavior Value");
|
|
}
|
|
}
|
|
|
|
if (!string.IsNullOrWhiteSpace(extractedClient))
|
|
{
|
|
if (_apiSecurityConfiguration.ExternalApiKeySet.TryGetValue(extractedClient, out var apiKey))
|
|
{
|
|
if (!apiKey.Equals(extractedApiKey))
|
|
{
|
|
switch (_apiSecurityConfiguration.ApiKeyAuthenticationFailureBehavior)
|
|
{
|
|
case ApiKeyAuthenticationFailureBehavior.Warn:
|
|
_logger.LogWarning(AuthMessages.AuthFailureMessage(extractedClient));
|
|
break;
|
|
case ApiKeyAuthenticationFailureBehavior.Error:
|
|
_logger.LogError(AuthMessages.AuthFailureMessage(extractedClient));
|
|
context.Response.StatusCode = 401;
|
|
await context.Response.WriteAsync(AuthMessages.AuthFailureMessage(extractedClient));
|
|
return;
|
|
default:
|
|
throw new Exception("Invalid ApiKeyAuthenticationFailureBehavior Value");
|
|
}
|
|
}
|
|
|
|
_logger.LogInformation($"Valid auth received for Client: {extractedClient}");
|
|
}
|
|
else
|
|
{
|
|
switch (_apiSecurityConfiguration.ApiKeyAuthenticationFailureBehavior)
|
|
{
|
|
case ApiKeyAuthenticationFailureBehavior.Warn:
|
|
_logger.LogWarning(AuthMessages.ClientNotFoundMessage());
|
|
break;
|
|
case ApiKeyAuthenticationFailureBehavior.Error:
|
|
_logger.LogError(AuthMessages.ClientNotFoundMessage());
|
|
context.Response.StatusCode = 401;
|
|
await context.Response.WriteAsync(AuthMessages.ClientNotFoundMessage());
|
|
return;
|
|
default:
|
|
throw new Exception("Invalid ApiKeyAuthenticationFailureBehavior Value");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (_apiSecurityConfiguration.ApiKeyAuthenticationFailureBehavior)
|
|
{
|
|
case ApiKeyAuthenticationFailureBehavior.Warn:
|
|
_logger.LogWarning(AuthMessages.EmptyKeySetMessage("ExternalApiKeySet"));
|
|
break;
|
|
case ApiKeyAuthenticationFailureBehavior.Error:
|
|
_logger.LogError(AuthMessages.EmptyKeySetMessage("ExternalApiKeySet"));
|
|
context.Response.StatusCode = 401;
|
|
await context.Response.WriteAsync(AuthMessages.EmptyKeySetMessage("ExternalApiKeySet"));
|
|
return;
|
|
default:
|
|
throw new Exception("Invalid ApiKeyAuthenticationFailureBehavior Value");
|
|
}
|
|
}
|
|
|
|
await _next(context);
|
|
}
|
|
}
|
|
} |