diff --git a/WorkFlow.API/Filters/APIKeyAuthHeaderOpFilter.cs b/WorkFlow.API/Filters/APIKeyAuthHeaderOpFilter.cs new file mode 100644 index 0000000..f9a6036 --- /dev/null +++ b/WorkFlow.API/Filters/APIKeyAuthHeaderOpFilter.cs @@ -0,0 +1,27 @@ +using Microsoft.Extensions.Options; +using Microsoft.OpenApi.Models; +using Swashbuckle.AspNetCore.SwaggerGen; +using WorkFlow.API.Models; + +namespace WorkFlow.API.Filters +{ + public class APIKeyAuthHeaderOpFilter(IOptions options) : IOperationFilter + { + private readonly APIKeyAuthOptions apiKeyAuthOptions = options.Value; + + public void Apply(OpenApiOperation operation, OperationFilterContext context) + { + var param = new OpenApiParameter + { + Name = apiKeyAuthOptions.HeaderName, + In = ParameterLocation.Header, + Required = true + }; + + if(apiKeyAuthOptions.SwaggerDescription is not null) + param.Description = apiKeyAuthOptions.SwaggerDescription; + + operation.Parameters = [param]; + } + } +} \ No newline at end of file diff --git a/WorkFlow.API/Models/APIKeyAuthOptions.cs b/WorkFlow.API/Models/APIKeyAuthOptions.cs index 75718c0..876c1f2 100644 --- a/WorkFlow.API/Models/APIKeyAuthOptions.cs +++ b/WorkFlow.API/Models/APIKeyAuthOptions.cs @@ -5,5 +5,7 @@ public required string Key { get; init; } public string HeaderName { get; init; } = "X-API-Key"; + + public string? SwaggerDescription { get; init; } = null; } } \ No newline at end of file diff --git a/WorkFlow.API/Program.cs b/WorkFlow.API/Program.cs index 25d99ce..19a783d 100644 --- a/WorkFlow.API/Program.cs +++ b/WorkFlow.API/Program.cs @@ -12,6 +12,7 @@ using NLog; using NLog.Web; using WorkFlow.API.Extensions; using Microsoft.Extensions.Configuration; +using WorkFlow.API.Filters; var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger(); logger.Info("Logging initialized."); @@ -36,9 +37,15 @@ try { Claims = user.ToClaimList().ToDictionary(claim => claim.Type, claim => claim.Value as object) }); - - if (config.GetSection("APIKeyAuth").Get() is APIKeyAuthOptions options) + + var apiKeyAuthSection = config.GetSection("APIKeyAuth"); + var useApiKey = false; + if (apiKeyAuthSection.Get() is APIKeyAuthOptions options) + { + builder.Services.Configure(apiKeyAuthSection); builder.Services.AddAPIKeyAuth(options); + useApiKey = true; + } builder.Services.AddControllers(); @@ -56,7 +63,11 @@ try }); builder.Services.AddEndpointsApiExplorer(); - builder.Services.AddSwaggerGen(); + builder.Services.AddSwaggerGen(c => + { + if(useApiKey) + c.OperationFilter(); + }); var app = builder.Build(); diff --git a/WorkFlow.API/appsettings.json b/WorkFlow.API/appsettings.json index aa629dc..fbc7ad8 100644 --- a/WorkFlow.API/appsettings.json +++ b/WorkFlow.API/appsettings.json @@ -65,6 +65,7 @@ }, "APIKeyAuth": { "Key": "ULbcOUiAXAoCXPviyCGtObZUGnrCHNgDmtNbQNpq5MOhB0EFQn18dObdQ93INNy8xIcnOPMJfEHqOotllELVrJ2R5AjqOfQszT2j00w215GanD3UiJGwFhwmdoNFsmNj", - "HeaderName": "X-API-Key" + "HeaderName": "X-API-Key", + "SwaggerDescription": "Required header for API key authentication. Enter a valid API key." } } \ No newline at end of file