Kłódki Swashbuckle Swagger UI z OAS3 [duplikat]
Mam interfejs API sieci Web ASP.Net Core Rest udokumentowany za pomocą generacji Swagger Swashbuckles (.net v5 i Swashbuckle.AspNetCore v5.6.3). Generuje dokumentację Swaggera i interfejs użytkownika z obsługą OAS3.
Również mój interfejs API używa tokenów okaziciela JWT. Więc dodałem ten kod do konfiguracji swaggera:
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{
In = ParameterLocation.Header,
Name = "Authorization",
Type = SecuritySchemeType.ApiKey,
Description = "Put `bearer` keyword in front of token"
});
options.AddSecurityRequirement(new OpenApiSecurityRequirement()
{
{
new OpenApiSecurityScheme()
{
Reference = new OpenApiReference()
{
Id = "Bearer",
Type = ReferenceType.SecurityScheme
}
},
Array.Empty<string>()
}
});
I zgodnie z oczekiwaniami dodał możliwość autoryzacji do interfejsu użytkownika Swagger:

Ale zauważyłem też kilka kłódek przy każdym żądaniu HTTP. Są odblokowane przed autoryzacją:

A po autoryzacji blokują:

Jak mogę sprawić, by te kłódki sygnalizowały, czy autoryzacja jest wymagana, czy nie (myślę, że widziałem gdzieś te same kłódki, które to robią i wydaje im się całkiem naturalne, że robią to również)?
Próbowałem już czegoś takiego, ale nie zadziałało (nagłówki żądań nie zawierały już tokenu jwt):
options.OperationFilter<SecurityRequirementsOperationFilter>();
Dowiedziałem się, że problem polega na tym, że mój Swagger używa OAS3 i jest SecurityRequirementsOperationFilter
zależny od OAS2. Próbowałem szukać alternatyw, ale wygląda na to, że nie ma podobnych narzędzi dla OAS3.
Co powinienem zrobić? Czy powinienem zapomnieć o tej funkcji? Ale to wygląda na jedyny cel tych zamków. Czy są jakieś sposoby, aby mieć tę funkcję i pozostać przy OAS3 (również nie jestem pewien, czy naprawdę potrzebuję obsługi OAS3 tak bardzo).
Odpowiedzi
Po kilku badaniach znalazłem odpowiedź tutaj: https://stackoverflow.com/a/61365691/13851956.
Więc kod to:
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
{
Description = "No need to put the `bearer` keyword in front of token",
Type = SecuritySchemeType.Http,
Scheme = "bearer",
BearerFormat = "JWT"
});
options.OperationFilter<AuthorizationOperationFilter>();
public class AuthorizationOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var actionMetadata = context.ApiDescription.ActionDescriptor.EndpointMetadata;
var isAuthorized = actionMetadata.Any(metadataItem => metadataItem is AuthorizeAttribute);
var allowAnonymous = actionMetadata.Any(metadataItem => metadataItem is AllowAnonymousAttribute);
if (!isAuthorized || allowAnonymous)
{
return;
}
operation.Parameters ??= new List<OpenApiParameter>();
operation.Security = new List<OpenApiSecurityRequirement>
{
new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Id = "Bearer",
Type = ReferenceType.SecurityScheme
}
},
Array.Empty<string>()
}
}
};
}
}
W rezultacie kłódki pojawiają się tylko obok działań oznaczonych [Authorize] i nie oznaczonych atrybutami [AllowAnonymous]:
