我正在使用.Net Core 2.1创建API,并使用JSON Web令牌(JWT)进行身份验证。
我有2个控制器:AuthenticationController
和UserController
。
我已经用AuthenticationController
装饰了[AllowAnonymous]
,并用UserController
装饰了[Authorize]
。
Swagger正常工作:它允许我在不请求授权的情况下访问AuthenticationController(注册/登录)中的端点,并且确实请求JWT在UserController
中访问端点。
但是,在Swagger UI中,每个控制器的每个端点都显示一个挂锁图标,好像它们都需要授权一样。一切正常且按预期运行,但令我烦恼的是,不需要授权的端点仍然显示该挂锁图标。
是否可以从这些端点中删除挂锁图标?
我相信OperationFilter
可以完成某些工作,但是我找不到办法。
答案 0 :(得分:3)
绝对,您需要使用IOperationFilter
来删除匿名端点的挂锁图标。
// AuthResponsesOperationFilter.cs
public class AuthResponsesOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var authAttributes = context.MethodInfo.DeclaringType.GetCustomAttributes(true)
.Union(context.MethodInfo.GetCustomAttributes(true))
.OfType<AuthorizeAttribute>();
if (authAttributes.Any())
{
var securityRequirement = new OpenApiSecurityRequirement()
{
{
// Put here you own security scheme, this one is an example
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
},
Scheme = "oauth2",
Name = "Bearer",
In = ParameterLocation.Header,
},
new List<string>()
}
};
operation.Security = new List<OpenApiSecurityRequirement> { securityRequirement };
operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" });
}
}
// Startup.cs
services.AddSwaggerGen(c =>
{
...
c.OperationFilter<AuthResponsesOperationFilter>();
};
不要忘记在您的AddSecurityRequirement
中删除对Startup.cs
的任何呼叫,否则挂锁图标仍将添加到所有端点。
答案 1 :(得分:0)
在startup.cs-> services.AddSwaggerGen中,您需要添加c.OperationFilter<ApplyOAuth2Security>();
并在stratup.cs中添加以下方法,这将在Swagger UI中启用标记为“仅授权”的操作方法的锁定/授权图标。
private class ApplyOAuth2Security : IOperationFilter
{
/// <inheritdoc/>
public void Apply(Operation operation, OperationFilterContext context)
{
var filterDescriptor = context.ApiDescription.ActionDescriptor.FilterDescriptors;
var isAuthorized = filterDescriptor.Select(filterInfo => filterInfo.Filter).Any(filter => filter is AuthorizeFilter);
var authorizationRequired = context.MethodInfo.CustomAttributes.Any(a => a.AttributeType.Name == "AuthorizeAttribute");
if (isAuthorized && authorizationRequired)
{
operation.Security = new List<IDictionary<string, IEnumerable<string>>>
{
new Dictionary<string, IEnumerable<string>>
{
{ "oauth2", new string[] { "openid" } },
},
};
}
}
}
答案 2 :(得分:0)
此解决方案适用于 SwashBuckle 5.0.0-rc5 和 .Net Core 3.1.1 Web API。 你需要:
public class AuthResponsesOperationFilter: IOperationFilter {
public void Apply(OpenApiOperation operation, OperationFilterContext context) {
if (!context.MethodInfo.GetCustomAttributes(true).Any(x => x is AllowAnonymousAttribute) &&
!context.MethodInfo.DeclaringType.GetCustomAttributes(true).Any(x => x is AllowAnonymousAttribute)) {
operation.Security = new List < OpenApiSecurityRequirement > {
new OpenApiSecurityRequirement {
{
new OpenApiSecurityScheme {
Reference = new OpenApiReference {
Type = ReferenceType.SecurityScheme,
Id = "bearer"
}
}, new string[] {}
}
}
};
}
}
}