Swashbuckle Swagger UI padlocks com OAS3 [duplicado]
Eu tenho um ASP.Net Core Rest Web API documentado com a geração Swagger do Swashbuckles (.net v5 e Swashbuckle.AspNetCore v5.6.3). Ele gera documentação Swagger e UI com suporte OAS3.
Além disso, minha API usa tokens de portador JWT. Então, adicionei este código à configuração swagger:
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>()
}
});
E como esperado, ele adicionou o recurso de autorização à IU do Swagger:

Mas também notei alguns cadeados ao lado de cada solicitação HTTP. Eles são desbloqueados antes da autorização:

E após a autorização eles bloqueiam:

Como posso fazer com que esses cadeados sinalizem se a autorização é necessária ou não (acho que já vi os mesmos cadeados em algum lugar fazendo isso e parece bastante natural para eles fazerem esse tipo de coisa também)?
Já tentei algo parecido, mas não funcionou (os cabeçalhos de solicitação não continham mais o token jwt):
options.OperationFilter<SecurityRequirementsOperationFilter>();
Eu descobri que o problema é que meu Swagger está usando OAS3 e SecurityRequirementsOperationFilter
dependendo do OAS2. Tentei procurar alternativas, mas parece que não existem ferramentas semelhantes para OAS3.
O que devo fazer? Devo esquecer esse recurso? Mas esse parece ser o único propósito dessas travas. Há alguma maneira de ter esse recurso e permanecer com o OAS3 (também não tenho certeza se realmente preciso tanto do suporte do OAS3).
Respostas
Depois de alguma pesquisa, encontrei a resposta aqui: https://stackoverflow.com/a/61365691/13851956.
Portanto, o código é:
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>()
}
}
};
}
}
O resultado é que os cadeados aparecem apenas ao lado das ações marcadas com [Autorizar] e não marcadas com atributos [PermitirAnônimo]:
