使用Swashbuckle和ASP.NET Identity在Swagger中限制对特定API控制器的访问

17
所以,我开始使用Swagger。我绝对喜欢它的功能,但我对其所有方法是否对公众开放有些疑虑。
据我了解,Swagger中包含的所有“auth”方法实际上都是关于API本身的,但我不需要在那里寻求帮助,因为我所有的API都受到API id/key pair保护。
我想通过利用ASP.NET Identity(登录系统)来限制对API页面(/swagger/ui/index)的访问。
有没有办法? Swaschbuckle中有任何方法吗?有任何路由/Identity hack吗?
非常感谢您的任何帮助。
编辑1:[ApiExplorerSettings(IgnoreApi = true)]属性不是我要找的 - 它限制了对所有方法的访问,而不考虑Identity。
3个回答

24

关于在Swagger文档中限制个别API的公开:

Swashbuckle 5.x:

Swashbuckle 5.x有一个名为IgnoreObsoleteActions的配置选项(需要设置,不是默认启用),如果操作具有[Obsolete]属性,则将隐藏该操作。

示例:配置

httpConfiguration
    .EnableSwagger(c =>
        {
            c.IgnoreObsoleteActions();
        });

更多信息可在文档中查看。

Swashbuckle 4.1.x(或者如果您不想使用过时的属性):

Swashbuckle在IApiExplorer基础上构建Swagger文档。您应该能够将一个属性[ApiExplorerSettings(IgnoreApi = true)]添加到控制器类或单独的控制器方法来管理ApiExplorerSettings,以便在生成文档时忽略它们(随后也会忽略Swashbuckle)。

示例:单个操作

/// Ignore 'GetFoo' in documentation
public class FooBarController
{
    [ApiExplorerSettings(IgnoreApi = true)]
    public Bar GetFoo
    {
       ...
    }

    public Bar GetBar
    {
       ...
    }
}

示例:控制器类

/// Ignore every controller method in FooBarController in documentation
[ApiExplorerSettings(IgnoreApi = true)]
public class FooBarController
{
    public Bar GetFoo
    {
       ...
    }

    public Bar GetBar
    {
       ...
    }
}

更多细节请参考GitHub问题。我自己在Swashbuckle 4.1.x中使用过。


1
你好。 非常感谢您的回复。 但是,不幸的是,[ApiExplorerSettings(IgnoreApi = true)]会将API从所有用户中隐藏,而不考虑他们在实际网站上的身份/角色/授权状态(以及AspUser)。 - Mike Neverov
1
谢谢您的回答!非常好用。 - jfl
它工作得非常好 - 很不错,可以隐藏我通常为小测试创建的一些端点。 - Mário Meyrelles

4
SwaggerAccessMessageHandler.cs类添加到您的项目中。 SwaggerAccessMessageHandler.cs:
public class SwaggerAccessMessageHandler : DelegatingHandler
{
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request,
        CancellationToken cancellationToken)
    {
        if (IsSwagger(request))
        {
            if (!Thread.CurrentPrincipal.Identity.IsAuthenticated)
            {
                // Unauthorized access to swagger 
                // do any things like : return Unauthorized or NotFound
                var response = request.CreateResponse(HttpStatusCode.Unauthorized);
                return Task.FromResult(response);

            }
        }

        return base.SendAsync(request, cancellationToken);
    }

    private bool IsSwagger(HttpRequestMessage request)
    {
         return request.RequestUri.PathAndQuery.StartsWith("/swagger");
    }
}

在启用 Swagger 之前,在你的 SwaggeConfig.cs(App_start>SwaggeConfig.cs)中添加处理程序:
public class SwaggerConfig
{
    public static void Register()
    {
        // Add here, before EnableSwagger
        GlobalConfiguration.Configuration.MessageHandlers.Add(new SwaggerAccessMessageHandler());

        GlobalConfiguration.Configuration
            .EnableSwagger(/*c => ....*/)
            .EnableSwaggerUi(/*c => ....*/);

    }
}

祝好。


2

在项目根目录创建了一个名为“swagger”的新文件夹。文件夹名称应与Swagger文档的URL匹配。

在新创建的文件夹中添加了新的Web.config文件。

<configuration> 
<system.web> 
<authorization> 
<deny users="?" /> 
</authorization> 
</system.web> 
<system.webServer> 
<modules runAllManagedModulesForAllRequests="true" /> 
</system.webServer> 
</configuration>

答案在这里找到。

另一个选择是:

"我想说的是,在这里你需要一个DelegatingHandler。"

答案在这里找到。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接