【问题标题】:How to remove swagger production .net core 2.1如何删除 swagger production .net core 2.1
【发布时间】:2019-07-29 12:06:42
【问题描述】:

我在多个微服务上大摇大摆地工作。 部署到 Azure 时,由于安全最佳实践,我们需要一起删除 swagger 选项。 使用 .net 核心 2.1 寻找定义的例子。

【问题讨论】:

    标签: swagger asp.net-core-2.0 swagger-ui


    【解决方案1】:

    首先,什么是“安全最佳实践”?将 API 文档用于生产并没有错。这实际上是重点:客户应该能够查看文档,以便他们可以正确使用您的 API。如果这些微服务不被外部客户端使用,那么问题就更小了,因为无论如何,外面的人都无法访问服务文档。如果服务是公开的,那么它们也应该要求对请求进行授权,并且可以通过相同的机制锁定文档本身。

    无论如何,如果您坚持在生产环境中删除它,最好的选择是一开始就不要添加它。换句话说,将所有 Swagger 设置包装在 Startup.csif (env.IsDevelopment()) 中,或者如果您希望它在暂存环境之类的东西中可用:if (!env.IsProduction())

    【讨论】:

    • 我并不完全同意这一点。您正确地指出,Swagger 的全部意义在于使您的客户能够正确使用您的 API。这变成了你想在这里让谁受益的问题。我与另一家公司合作构建产品,我们使用 Swagger 作为普遍认可的 API。在开发中。但这并不意味着我们希望互联网上的任何用户都可以使用 API。事实上,我们没有。我们只希望我们的移动应用程序能够成功。没有其他的。因此,在这种情况下,让 Swagger 在生产中公开可用是一个很大的“不可能”。为什么要冒险?
    • 再一次,这就是授权的用途。它要么暴露在互联网上,要么没有。
    • 我建议尽量减少攻击向量是主要因素。如果公众没有业务调用您的 API,则不应向他们提供任何有关它的信息(通过 Swagger)。正如我所说,这将视具体情况而定。如果我的 API 有一系列客户,那绝对是。但如果只是另一个开发团队帮助开发了一个应用程序(他们做应用程序,我做 API),那么我不会在生产中公开 Swagger。不会有太多收获。
    • 我不同意这一点,因为大多数由开发人员开发的现代应用程序都是基于与 API 通信的现代 UI 框架。在这种情况下,启用 swagger 可能会导致解决方案设计的泄漏,因为所有 API 和模型对其他人都是可见的。但我同意,如果我们有适当的安全性,那么我们可以控制 API 的执行。
    • 我实际上在脑海中也有同样的对话,关于 swagger 是否应该托管在 API 服务上,我得出的结论是“不”。我使用 swagger 来帮助开发,但随后在构建管道中,提取 swagger.yaml 并将其托管在指向 API 的服务器上,并让 API 自行托管。我认为我不需要在每个 API 调用中加载 swashbuckle 对象所增加的延迟(无论多么轻微)。它还允许我以个人身份管理documentationservice
    【解决方案2】:

    如果您是从 .net core 3.1 开始的:

    假设 Startup 类的构造函数将注入的 IConfiguration 复制到名为 configuration 的本地字段,那么您可以像这样设置 Configure 方法:

    public void configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        var applicationName = configuration.GetValue<string>("ApplicationName") ?? "MyApi";
        var basePath = configuration.GetValue<string>("BasePath");
        if (!string.IsNullOrEmpty(basePath))
            app.UsePathBase(basePath);
    
        if (!env.IsProduction())
        {
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                c.SwaggerEndpoint($"{basePath}/swagger/v1/swagger.json",
                                    $"{applicationName} {ReflectionUtils.GetAssemblyVersion<Program>()}");
            });
        }
    }
    
    

    【讨论】:

      【解决方案3】:

      第一个选项,在配置方法中禁用它:

          public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
          {
              // read from config
              var config = (IConfiguration)app.ApplicationServices.GetService(typeof(IConfiguration));
      
              enableSwagger = bool.Parse(config.GetValue<string>("EnableSwagger") ?? "false");
      
              if (enableSwagger /*|| env.IsDevelopment()*/)
              {
                  app.UseSwagger(o =>
                  {
                      o.RouteTemplate = "swagger/{documentName}/swagger.json";
                  });
      
                  // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.),
                  // specifying the Swagger JSON endpoint.
                  app.UseSwaggerUI(c =>
                  {
                      c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
                  });
              }
          }
      

      或使用:

      if (env.IsDevelopment())
      {
         ...
      }
      

      第二种选择是完全删除代码文件中的所有引用和使用

      #if USE_SWAGGER
      using Microsoft.OpenApi.Models;
      ...
      #endif
      
      #if USE_SWAGGER
      <some method>
      ...
      #endif
      

      添加.csproj:

      <Choose>
        <When Condition="$(DefineConstants.Contains('USE_SWAGGER'))">
          <ItemGroup Condition="'$(TargetFramework)' == 'netstandard3.1'">
          <PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="5.6.3" />
          <PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.6.3" />
          <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="5.6.3" />
          </ItemGroup>
        </When>
        <Otherwise />
      </Choose>
      

      <Choose>
        <When Condition="'$(Configuration)' == 'Debug'">
          <ItemGroup Condition="'$(TargetFramework)' == 'netstandard3.1'">
          <PackageReference Include="Swashbuckle.AspNetCore.Swagger" Version="5.6.3" />
          <PackageReference Include="Swashbuckle.AspNetCore.SwaggerGen" Version="5.6.3" />
          <PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="5.6.3" />
          </ItemGroup>
        </When>
        <Otherwise />
      </Choose>
      

      玩一玩,你就会变得深刻!

      【讨论】:

        【解决方案4】:

        您也可以在您不想在文档中显示的控制器类中使用[ApiExplorerSettings(IgnoreApi = true)]。这是一个排除操作,意味着将显示每个类,除了标有此属性的类。 (当您只想让第三方消费者看到您的一组 API 文档时,这很好);

        【讨论】:

          猜你喜欢
          • 2018-11-10
          • 1970-01-01
          • 1970-01-01
          • 2018-12-25
          • 2019-08-03
          • 2020-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多