【问题标题】:In Swagger UI, how can I remove the padlock icon from "anonymous" methods?在 Swagger UI 中,如何从“匿名”方法中删除挂锁图标?
【发布时间】:2019-11-06 19:14:37
【问题描述】:

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

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

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

但是,在 Swagger UI 中,每个控制器的每个端点都会显示一个挂锁图标,就好像它们都需要授权一样。一切都按预期正常工作,但令我困扰的是,不需要授权的端点仍然显示挂锁图标。

有没有办法从这些端点移除挂锁图标?

我相信OperationFilter 可以做一些事情,但我找不到方法。

【问题讨论】:

  • 你能解决这个问题吗?

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


【解决方案1】:

当然,您需要使用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>();
};

不要忘记删除您的Startup.cs 中对AddSecurityRequirement 的任何调用,否则挂锁图标仍会添加到所有端点。

【讨论】:

    【解决方案2】:

    此解决方案适用于 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[] {}
              }
            }
          };
        }
    
      }
    }

    【讨论】:

      【解决方案3】:

      在 startup.cs -> services.AddSwaggerGen 中,您需要添加 c.OperationFilter&lt;ApplyOAuth2Security&gt;(); 并在 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" } },
                              },
                          };
                      }
                  }
              }
      

      【讨论】:

        猜你喜欢
        • 2021-04-01
        • 1970-01-01
        • 2022-12-17
        • 2018-10-18
        • 1970-01-01
        • 1970-01-01
        • 2022-10-15
        • 2020-03-23
        • 2015-08-10
        相关资源
        最近更新 更多