.NET-5 对未经授权的用户隐藏 swagger 端点

Mic*_*h91 5 swagger-ui openapi .net-5

我有一个使用 OpenApi 的 .NET 5 API。

\n

是否可以在用户获得 JWT 持有者令牌授权之前隐藏所有 API 端点(但登录端点除外)?

\n

这是我在startup.cs中使用的代码

\n
services.AddSwaggerGen(c =>\n        {\n            c.SwaggerDoc("v1", new OpenApiInfo { \n                Title = "API", Version = "v1",\n                Description = "API (.NET 5.0)",\n                Contact = new OpenApiContact()\n                {\n                    Name = "Contact",\n                    Url = null,\n                    Email = "email@email.com"\n                }\n            });\n            c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme\n            {\n                Description = @"Autorizaci\xc3\xb3n JWT utilizando el esquema Bearer en header. <br />\n                  Introducir el token JWT generado por AuthApi.",\n                Name = "Authorization",\n                In = ParameterLocation.Header,\n                Type = SecuritySchemeType.Http,\n                Scheme = "Bearer"\n            });\n            c.AddSecurityRequirement(new OpenApiSecurityRequirement()\n  {\n    {\n      new OpenApiSecurityScheme\n      {\n        Reference = new OpenApiReference\n          {\n            Type = ReferenceType.SecurityScheme,\n            Id = "Bearer"\n          },\n          Scheme = "oauth2",\n          Name = "Bearer",\n          In = ParameterLocation.Header,\n\n        },\n        new List<string>()\n      }\n    });\n        });\n
Run Code Online (Sandbox Code Playgroud)\n

Mic*_*h91 1

我最终使用 appsettings.json 参数隐藏了 swagger enpoints,这并不完全是我所要求的,但我会发布解决方案,以防它可以帮助某人,因为它可能可以过滤登录用户:

有一些注释块和未使用的代码可能对您有用,因为它附带了我在网上找到的示例。

Swagger 忽略过滤器类:

public class SwaggerIgnoreFilter : IDocumentFilter
{
    private IServiceProvider _provider;

    public SwaggerIgnoreFilter(IServiceProvider provider)
    {
        if (provider == null) throw new ArgumentNullException(nameof(provider));

        this._provider = provider;
    }
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        var allTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(i => i.GetTypes()).ToList();

        var http = this._provider.GetRequiredService<IHttpContextAccessor>();
        var authorizedIds = new[] { "00000000-1111-2222-1111-000000000000" };   // All the authorized user id's.
                                                                                // When using this in a real application, you should store these safely using appsettings or some other method.
        var userId = http.HttpContext.User.Claims.Where(x => x.Type == "jti").Select(x => x.Value).FirstOrDefault();
        var show = http.HttpContext.User.Identity.IsAuthenticated && authorizedIds.Contains(userId);
        //var Securitytoken = new JwtSecurityTokenHandler().CreateToken(tokenDescriptor);
        //var tokenstring = new JwtSecurityTokenHandler().WriteToken(Securitytoken);
        //var token = new JwtSecurityTokenHandler().ReadJwtToken(tokenstring);
        //var claim = token.Claims.First(c => c.Type == "email").Value;
        Parametros parametros = new Parametros();
        if (!show)
        {
            var descriptions = context.ApiDescriptions.ToList();

            foreach (var description in descriptions)
            {
                // Expose login so users can login through Swagger. 
                if (description.HttpMethod == "POST" && description.RelativePath == "denarioapi/v1/auth/login")
                    continue;

                var route = "/" + description.RelativePath.TrimEnd('/');
                OpenApiPathItem path;
                swaggerDoc.Paths.TryGetValue(route, out path);

                switch(route)
                {
                    case string s when s.Contains("/Contabilidad"):
                        if (parametros.contabilidadApi != "1")
                        {
                            swaggerDoc.Paths.Remove(route);
                        }
                        break;
                    case string s when s.Contains("/Identificativos"):
                        if (parametros.identificativosApi != "1")
                        {
                            swaggerDoc.Paths.Remove(route);
                        }
                        break;
                    case string s when s.Contains("/Centros"):
                        if (parametros.centrosApi != "1")
                        {
                            swaggerDoc.Paths.Remove(route);
                        }
                        break;
                    case string s when s.Contains("/Contratos"):
                        if (parametros.contratosApi != "1")
                        {
                            swaggerDoc.Paths.Remove(route);
                        }
                        break;
                    
                    case string s when s.Contains("/Planificacion"):
                        if (parametros.planificacionApi != "1")
                        {
                            swaggerDoc.Paths.Remove(route);
                        }
                        break;
                    case string s when s.Contains("/Puestotrabajo"):
                        if (parametros.puestotrabajoApi != "1")
                        {
                            swaggerDoc.Paths.Remove(route);
                        }
                        break;
                    
                    case string s when s.Contains("/Usuarios"):
                        if (parametros.usuariosApi != "1")
                        {
                            swaggerDoc.Paths.Remove(route);
                        }
                        break;
                    
                    default:
                        break;
                }

                // remove method or entire path (if there are no more methods in this path)
                //switch (description.HttpMethod)
                //{
                    //case "DELETE": path. = null; break;
                    //case "GET": path.Get = null; break;
                    //case "HEAD": path.Head = null; break;
                    //case "OPTIONS": path.Options = null; break;
                    //case "PATCH": path.Patch = null; break;
                    //case "POST": path.Post = null; break;
                    //case "PUT": path.Put = null; break;
                    //default: throw new ArgumentOutOfRangeException("Method name not mapped to operation");
                //}

                //if (path.Delete == null && path.Get == null &&
                //    path.Head == null && path.Options == null &&
                //    path.Patch == null && path.Post == null && path.Put == null)
                //swaggerDoc.Paths.Remove(route);
            }

        }




        foreach (var definition in swaggerDoc.Components.Schemas)
        {
            var type = allTypes.FirstOrDefault(x => x.Name == definition.Key);
            if (type != null)
            {
                var properties = type.GetProperties();
                foreach (var prop in properties.ToList())
                {
                    var ignoreAttribute = prop.GetCustomAttribute(typeof(OpenApiIgnoreAttribute), false);

                    if (ignoreAttribute != null)
                    {
                        definition.Value.Properties.Remove(prop.Name);
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Startup.cs配置服务:

services.AddSwaggerGen(c =>
        {
            c.SwaggerDoc("v1", new OpenApiInfo
            {
                Title = "API",
                Version = "v1",
                Description = "API (.NET 5.0)",
                Contact = new OpenApiContact()
                {
                    Name = "Contact name",
                    Url = null,
                    Email = "email@email.com"
                }
            });
            c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
            {
                Description = @"Description",
                Name = "Authorization",
                In = ParameterLocation.Header,
                Type = SecuritySchemeType.Http,
                Scheme = "Bearer"
            });
            c.DocumentFilter<SwaggerIgnoreFilter>();
            c.AddSecurityRequirement(new OpenApiSecurityRequirement()
  {
        {
          new OpenApiSecurityScheme
          {
            Reference = new OpenApiReference
              {
                Type = ReferenceType.SecurityScheme,
                Id = "Bearer"
              },
              Scheme = "oauth2",
              Name = "Bearer",
              In = ParameterLocation.Header,

            },
            new List<string>()
          }
    });
        });
Run Code Online (Sandbox Code Playgroud)