17

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.

Mike Neverov
  • 309
  • 1
  • 2
  • 7

3 Answers3

24

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.

Anthony Neace
  • 25,013
  • 7
  • 114
  • 129
  • 1
    Hello. I really appreciate the response. But, unfortunately, [ApiExplorerSettings(IgnoreApi = true)] hides the api from all the users, without his Identity/roles/auth status on the actual site (and AspUser) – Mike Neverov Oct 17 '15 at 18:43
  • 1
    Thank you for this answer! Works great. – jfl Feb 25 '16 at 08:37
  • It works great - nice to hide some endpoints that I usually create for small tests. – Mário Meyrelles Mar 10 '17 at 17:36
4

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.

D.L.MAN
  • 990
  • 12
  • 18
2

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.

pirin
  • 51
  • 4