在Swagger用户界面中,如何从“匿名”方法中删除挂锁图标?

时间:2019-06-25 01:36:36

标签: jwt swagger asp.net-core-webapi asp.net-core-2.1

我正在使用.Net Core 2.1创建API,并使用JSON Web令牌(JWT)进行身份验证。

我有2个控制器:AuthenticationControllerUserController。 我已经用AuthenticationController装饰了[AllowAnonymous],并用UserController装饰了[Authorize]

Swagger正常工作:它允许我在不请求授权的情况下访问AuthenticationController(注册/登录)中的端点,并且确实请求JWT在UserController中访问端点。

但是,在Swagger UI中,每个控制器的每个端点都显示一个挂锁图标,好像它们都需要授权一样。一切正常且按预期运行,但令我烦恼的是,不需要授权的端点仍然显示该挂锁图标。

是否可以从这些端点中删除挂锁图标?

我相信OperationFilter可以完成某些工作,但是我找不到办法。

3 个答案:

答案 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。 你需要:

  1. 实现 IOperationFilter 接口,
  2. 添加 c.OperationFilter();在您的 Startup.cs 文件中
  3. 最后删除对 AddSecurityRequirement 的任何调用

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[] {}
          }
        }
      };
    }

  }
}