andrewb
andrewb

Reputation: 3095

Add basic auth to swagger ui so the documentation pages are locked down

.Net framework 4.6.1, class library project (web API)

I have added the swagger/swashbuckle nuget to the project, and added the SwaggerConfig.cs file to my App_Start folder.

Snip of SwaggerConfig.cs

using System.Web.Http;
using WebActivatorEx;
using MyService;
using Swashbuckle.Application;

[assembly: PreApplicationStartMethod(typeof(SwaggerConfig), "Register")]

I then go on and register the service

public class SwaggerConfig
{
    public static void Register()
    {
        var thisAssembly = typeof(SwaggerConfig).Assembly;

        GlobalConfiguration.Configuration
            .EnableSwagger(c =>
                {
                    c.SingleApiVersion("v1", "My API");
                    c.IncludeXmlComments(string.Format(@"{0}\swaggerdoc.XML",
                       System.AppDomain.CurrentDomain.BaseDirectory));
                    c.BasicAuth("basicauth").Description("Basic HTTP Authentication");
                })
            .EnableSwaggerUi(c =>
                {
                });
    }
}

But I am not sure where I set the username/password required to view the documentation. The API methods all use a token for authentication, but I am trying to add a layer of security to stop a random user stumbling across the API documentation, by using basic auth.

Upvotes: 3

Views: 3738

Answers (2)

Mamdouh Emam
Mamdouh Emam

Reputation: 345

To secure your swagger doc's using your basic authentication, you will need to enable it in the SwaggerConfig.cs file and couple it with a corresponding "security" property at the document or operation level.

Please note the below full comment from the SwaggerConfig.cs for Enabling Basic Authentication:

// You can use "BasicAuth", "ApiKey" or "OAuth2" options to describe security schemes for the API.
// See https://github.com/swagger-api/swagger-spec/blob/master/versions/2.0.md for more details.
// NOTE: These only define the schemes and need to be coupled with a corresponding "security" property
// at the document or operation level to indicate which schemes are required for an operation. To do this,
// you'll need to implement a custom IDocumentFilter and/or IOperationFilter to set these properties
// according to your specific authorization implementation
//
c.BasicAuth("basic").Description("Basic HTTP Authentication");

how to couple it with the corresponding "security" property? You can add a class to implement that filter as:

public class SwaggerHeaderFilter : IOperationFilter
{

    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        var filterPipeline = apiDescription.ActionDescriptor.GetFilterPipeline();
        // check if authorization is required
        var isAuthorized = filterPipeline
            .Select(filterInfo => filterInfo.Instance)
            .Any(filter => filter is IAuthorizationFilter);
        // check if anonymous access is allowed
        var allowAnonymous = apiDescription.ActionDescriptor.GetCustomAttributes<AllowAnonymousAttribute>().Any();
        if (isAuthorized && !allowAnonymous)
        {
            if (operation.security == null)
                operation.security = new List<IDictionary<string, IEnumerable<string>>>();
            var auth = new Dictionary<string, IEnumerable<string>>
                 {
                    {"basic", Enumerable.Empty<string>()}
                };
            operation.security.Add(auth);
        }
    }
}

and in the swaggerConfig.cs file, add this to the configurations:

c.OperationFilter<SwaggerHeaderFilter>();

And Don't forget to decorate your Api's with the [Authorize] tag

reference: https://codingsight.com/swashbuckle-swagger-configuration-for-webapi/

Upvotes: 1

Marc Wittke
Marc Wittke

Reputation: 3155

If you want to secure the documentation, you have to to this on the webserver itself, with .net 4.x I assume IIS.

The method you are using is intended to tell Swagger to show a username/password logon form to call the service endpoints using these credentials with a basic HTTP authorization header.

Upvotes: 1

Related Questions