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

Posted

技术标签:

【中文标题】在 Swagger UI 中,如何从“匿名”方法中删除挂锁图标?【英文标题】:In Swagger UI, how can I remove the padlock icon from "anonymous" methods? 【发布时间】: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 可以做一些事情,但我找不到方法。

【问题讨论】:

你能解决这个问题吗? 【参考方案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。 你需要:

    实现一个 IOperationFilter 接口, 添加 c.OperationFilter();在您的 Startup.cs 文件中 最终移除对 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"  ,
                        ,
                    ;
                
            
        

【讨论】:

以上是关于在 Swagger UI 中,如何从“匿名”方法中删除挂锁图标?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swagger-UI 中打开本地文件

如何让 Swagger 在生成的 HTML(在 Swagger UI 页面中)中添加新行?

如何在 Swagger UI 中发送带有请求的自定义标头?

Azure Functions 和 Swagger UI - 如何在 swagger UI 中显示查询字符串参数?

如何更改 swagger-ui.html 默认路径

在 Swagger UI 中,如何自定义 body 输入 ui(模型架构 UI)