I am trying to improve my projects openapi definition by adding security requirements to endpoints that require authentication.
An endpoint requires authentication if it is a method of a class with the [Authorize]
decorator, and lacks a [AllowAnonymous]
decorator.
I am trying to use IOperationFilter
to add security requirements based on this, but i am struggling with filter descriptors - I am not able to find any documentation on how these work whatsoever.
This is my current filter that i based on another StackOverflow thread:
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace OpenData.Filters {
public class AddAuthHeaderOperationFilter : IOperationFilter
{
private readonly IHttpContextAccessor httpContextAccessor;
public AddAuthHeaderOperationFilter(IHttpContextAccessor httpContextAccessor)
{
this.httpContextAccessor = httpContextAccessor;
}
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var filterDescriptor = context.ApiDescription.ActionDescriptor.FilterDescriptors;
var isAuthorized = filterDescriptor.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter);
var allowAnonymous = filterDescriptor.Select(filterInfo => filterInfo.Filter).Any(filter => filter is IAllowAnonymousFilter);
if (/*isAuthorized && */!allowAnonymous)
{
operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" });
operation.Responses.Add("403", new OpenApiResponse { Description = "Forbidden" });
//Add JWT bearer type
operation.Security.Add(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
},
Scheme = "Bearer",
Name = "Bearer",
In = ParameterLocation.Header,
},
new List<string>()
}
});
}
}
}
}
My problem is the filterDescriptor
part. How do i use this to detect if what i am currently applying is a method of a class with an [Authorize]
decorator, if it is, if it has a [AllowAnonymous]
decorator? I might be misusing terms as well, it is a method like this i want to detect:
[Authorize]
[Route("/api/[controller]")]
public class CommentController : Controller
{
[AllowAnonymous]
[HttpGet("metadata/{metadataUuid}")]
public async Task<IActionResult> GetCommentsForMetadataAsync(Guid metadataUuid)
{
// ...
}
Researching this has been a pain, there doesn't seem to be any easily available documentation for this API on the web, and i haven't been able to find any examples for this version of dotnetcore/swagger either.
My versions:
- .netcore 3.1
- Swashbuckle.AspNetCore 5.0.0