Swashbuckle.WebApi
Swashbuckle.WebApi copied to clipboard
Provide a way to generate an empty JSON security array for an operation
In order to mark operations as requiring authorization in a Swagger document, you can individually mark them one-by-one as requiring security:
services.AddSwaggerGen(options => {
options.OperationFilter<SwaggerRequireAuth>(apiScope);
});
//...
internal class SwaggerRequireAuth : IOperationFilter {
private readonly string _apiScope;
public SwaggerNoAnonymousAuth(string apiScope) {
_apiScope = apiScope;
}
public void Apply(OpenApiOperation operation, OperationFilterContext context) {
bool isAnonymous = context.MethodInfo.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Count() > 0;
if (!isAnonymous) {
operation.Security = new List<OpenApiSecurityRequirement> {
new OpenApiSecurityRequirement {
{
// Scheme required to access all non-anonymous API operations
new OpenApiSecurityScheme {
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
},
// Scopes required to access all non-anonymous API operations
new[] { _apiScope }
}
}
};
}
}
}
However, this will rather bloat the Swagger JSON file by separately specifying the same security for every single operation:
"security": [
{
"oauth2": [
"my-api-scope"
]
}
]
If your API has only a few operations that are anonymous, and don't require authentication, with every other operation requiring the same authentication, the more efficient way to indicate this is to apply a global security requirement and then specify an empty JSON security array for the few operations that are anonymous:
services.AddSwaggerGen(options => {
options.AddSecurityRequirement(new OpenApiSecurityRequirement {
{
// Scheme required to access all non-anonymous API operations
new OpenApiSecurityScheme {
Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "oauth2" }
},
// Scopes required to access all non-anonymous API operations
new[] { apiScope }
}
});
});
//...
internal class SwaggerNoAnonymousAuth : IOperationFilter {
private readonly string _apiScope;
public SwaggerNoAnonymousAuth(string apiScope) {
_apiScope = apiScope;
}
public void Apply(OpenApiOperation operation, OperationFilterContext context) {
bool isAnonymous = context.MethodInfo.GetCustomAttributes(true).OfType<AllowAnonymousAttribute>().Count() > 0;
if (isAnonymous) {
operation.Security = new List<OpenApiSecurityRequirement>();
}
}
}
... to generate:
"security": []
At least, that's what I wish it would generate, which should mark the few anonymous methods I have as anonymous in the Swagger document. Unfortunately, setting .Security
to an empty list removes the security element altogether, meaning the operation gets the global security applied to it.
Can a way be added to get the Swagger document to have an empty JSON security array for certain operations?