简体   繁体   中英

Restrict access to certain API controllers in Swagger using Swashbuckle and ASP.NET Identity

So, I started using Swagger. I'm absolutely in love with it's features, but I have some doubts on availability of all methods to public.

As far as I understood - all included in Swaschbuclke "auth" methods are actually about APIs itself, but I don't need help there - all of my APIs are protected by API id/key pair.

I would like to somehow utilise ASP.NET Identity (login system) to restrict access to API page (/swagger/ui/index).

Is there any way? Any methods in Swaschbuckle? Any routes/Identity hacks?

Any help is appreciated.

Edit 1: [ApiExplorerSettings(IgnoreApi = true)] attribute is not what I'm looking for - it restricts all the access to the methods, regardless of Identity.

Concerning restricting exposure of individual APIs in your swagger documentation:

Swashbuckle 5.x:

Swashbuckle 5.x has a configuration option called IgnoreObsoleteActions (that you need to set; it isn't enabled by default) that will hide actions if they have the [Obsolete] attribute.

Example: Configuration

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

More info available in the documentation .

Swashbuckle 4.1.x (or if you don't want to use the obsolete attribute):

Swashbuckle builds the swagger documentation on top of IApiExplorer . You should be able to add an attribute -- [ApiExplorerSettings(IgnoreApi = true)] -- to manage ApiExplorerSettings the controller class or individual controller methods to have the explorer (and subsequently, Swashbuckle) ignore them when generating the documentation.

Example: Individual actions

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

    public Bar GetBar
    {
       ...
    }
}

Example: Controller classes

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

    public Bar GetBar
    {
       ...
    }
}

More details in this GitHub Issue . I've used this myself in Swashbuckle 4.1.x.

Add SwaggerAccessMessageHandler.cs class to your project.

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");
    }
}

add the handler in your SwaggeConfig.cs (App_start>SwaggeConfig.cs) just before enabling Swagger:

public class SwaggerConfig
{
    public static void Register()
    {
        // Add here, before EnableSwagger
        GlobalConfiguration.Configuration.MessageHandlers.Add(new SwaggerAccessMessageHandler());

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

    }
}

best regard.

Created new folder called "swagger" in the project root. The folder name should match the url to the swagger documentation.

Added new Web.config file in the newly created folder.

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

answer found here .

Another option will be:

"Off the top of my head I would say a DelegatingHandler is what you need here."

answer found here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM