130 lines
6.1 KiB
C#
130 lines
6.1 KiB
C#
using LCU.Library.Internal.ApiSecurity.Constants;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Microsoft.AspNetCore.Mvc.Filters;
|
|
using LCU.Library.Internal.ApiSecurity.Enums;
|
|
using LCU.Library.Internal.ApiSecurity.Models;
|
|
using Microsoft.Extensions.DependencyInjection;
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
namespace LCU.Library.Internal.ApiSecurity.Attributes;
|
|
|
|
[AttributeUsage(validOn: AttributeTargets.Method)]
|
|
public class ApiKeyAttribute : Attribute, IAsyncActionFilter
|
|
{
|
|
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
|
{
|
|
var apiSecurityConfiguration = context.HttpContext.RequestServices.GetRequiredService<ApiSecurityConfiguration>();
|
|
var logger = context.HttpContext.RequestServices.GetRequiredService<ILoggerFactory>().CreateLogger(GetType().Name);
|
|
|
|
if (apiSecurityConfiguration.ExternalApiKeySet.Any())
|
|
{
|
|
if (!context.HttpContext.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.Result = new ContentResult()
|
|
{
|
|
StatusCode = 401,
|
|
Content = AuthMessages.NotProvidedMessage(HeaderKeys.ApiKey)
|
|
};
|
|
return;
|
|
default:
|
|
throw new Exception("Invalid ApiKeyAuthenticationFailureBehavior Value");
|
|
}
|
|
}
|
|
|
|
if (!context.HttpContext.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.Result = new ContentResult()
|
|
{
|
|
StatusCode = 401,
|
|
Content = 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.Result = new ContentResult()
|
|
{
|
|
StatusCode = 401,
|
|
Content = 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.Result = new ContentResult()
|
|
{
|
|
StatusCode = 401,
|
|
Content = 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.Result = new ContentResult()
|
|
{
|
|
StatusCode = 401,
|
|
Content = AuthMessages.EmptyKeySetMessage("ExternalApiKeySet")
|
|
};
|
|
return;
|
|
default:
|
|
throw new Exception("Invalid ApiKeyAuthenticationFailureBehavior Value");
|
|
}
|
|
}
|
|
|
|
await next();
|
|
}
|
|
} |