ASP.NET Core - Swagger - 公共和私有 swagger 页面

QTo*_*Tom 9 c# swagger swagger-ui swashbuckle asp.net-core

我们有一个 API,其中包含一些我们想要公开公开的端点,以及一些我们不公开的端点。但是,我并不想简单地排除专用端点,我仍然希望它们可见,但仅限于某些用户或至少在不同的 url 下。这看起来应该很常见,但我无法找到如何做到这一点。

目前,我们已设置并运行 swagger,显示所有端点。ApiExplorerSettings一些控制器使用如下属性标记为“公共”组(其中SwaggerGroups.Public是字符串常量“public”):

[ApiExplorerSettings(GroupName = SwaggerGroups.Public)]
Run Code Online (Sandbox Code Playgroud)

理想情况下,我们会拥有一个显示所有标记为公共的控制器/方法的 swagger 页面,以及另一个显示所有端点的密码保护端点。这可能吗?

Tse*_*eng 7

首先,您的问题听起来像是您没有正确分离 API,实际上它应该是两个 api(微服务术语中的两个应用程序服务)。

因此,您也应该将其视为两个单独的 API。

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("public", new OpenApiInfo { Title = "My Public API", Version = "v1" });
    c.SwaggerDoc("private", new OpenApiInfo { Title = "My Private API", Version = "v1" });
});
Run Code Online (Sandbox Code Playgroud)

这将生成两个不同的 OpenAPI (Swagger) 规范。/api-docs/public/swagger.json/api-docs/private/swagger.json,可以托管在两个不同的 UI 应用程序中(一个受保护,另一个公开可用)

// Public Docs Api
app.UseSwaggerUI(c =>
{
    // we use absolute uri here, since the swagger.json is outside of this application
    c.SwaggerEndpoint("http://example.com/api-docs/public/swagger.json", "Public API");
});


// Private Docs App
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("http://example.com/api-docs/private/swagger.json", "Private API");
});
Run Code Online (Sandbox Code Playgroud)

另一种方法是使用构建管道/持续集成系统。Swashbuckle.AspNetCore 在 5.x 版本的库中提供了 cli 扩展,它可以作为构建脚本的一部分执行,以swagger.json在构建过程中生成文件。

例如

dotnet swagger tofile --output ../swagger/myapi/private.json MyCompany.MyApplication.Mvc private
dotnet swagger tofile --output ../swagger/myapi/public.json MyCompany.MyApplication.Mvc public
Run Code Online (Sandbox Code Playgroud)

并有一个像这样的文档应用程序

// Private Docs App
app.UseSwaggerUI(c =>
{
    c.SwaggerEndpoint("http://example.com/api-docs/swagger/myapp/private.json", "Private API");
    c.SwaggerEndpoint("http://example.com/api-docs/swagger/myapp/public.json", "Public API");
});
Run Code Online (Sandbox Code Playgroud)

您使用 Web 服务器手段(nginx、apache、iis)保护“private.json”,即仅允许在内部网络中或仅在身份验证后访问 private.json 等。

上述方法的替代方案是将两个文件托管在同一个应用程序中,但使用中间件保护私有文件,请参阅此 GitHub 问题以获取一些灵感。