How to send custom headers with requests in Swagger UI?

ApiAuthorizationSwaggerSwagger Ui

Api Problem Overview


I have some endpoints in the API - /user/login, /products.

In Swagger UI I post email and password to /user/login and as a response I receive a token string.

Then, I can copy the token from the response and want to use it as Authorization header value in requests to all urls if it's present, and to /products as an example.

Should I create a text input manually somewhere on the Swagger UI page, then put the token there and somehow inject in the requests or are there tools to manage it in a better way?

Api Solutions


Solution 1 - Api

In ASP.NET Web API, the simplest way to pass-in a header on Swagger UI is to implement the Apply(...) method on the IOperationFilter interface.

Add this to your project:

public class AddRequiredHeaderParameter : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription)
    {
        if (operation.parameters == null)
            operation.parameters = new List<Parameter>();

        operation.parameters.Add(new Parameter
        {
            name = "MyHeaderField",
            @in = "header",
            type = "string",
            description = "My header field",
            required = true
        });
    }
}

In SwaggerConfig.cs, register the filter from above using c.OperationFilter<T>():

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

    GlobalConfiguration.Configuration 
        .EnableSwagger(c =>
        {
            c.SingleApiVersion("v1", "YourProjectName");
            c.IgnoreObsoleteActions();
            c.UseFullTypeNameInSchemaIds();
            c.DescribeAllEnumsAsStrings();
            c.IncludeXmlComments(GetXmlCommentsPath());
            c.ResolveConflictingActions(apiDescriptions => apiDescriptions.First());


            c.OperationFilter<AddRequiredHeaderParameter>(); // Add this here
        })
        .EnableSwaggerUi(c =>
        {
            c.DocExpansion(DocExpansion.List);
        });
}

Solution 2 - Api

You can add a header parameter to your request, and Swagger-UI will show it as an editable text box:

swagger: "2.0"
info:
  version: 1.0.0
  title: TaxBlaster
host: taxblaster.com
basePath: /api
schemes:
- http

paths:

  /taxFilings/{id}:

    get:
      parameters:
      - name: id
        in: path
        description: ID of the requested TaxFiling
        required: true
        type: string
      - name: auth
        in: header
        description: an authorization header
        required: true
        type: string
      responses:
        200:
          description: Successful response, with a representation of the Tax Filing.
          schema:
            $ref: "#/definitions/TaxFilingObject"
        404:
          description: The requested tax filing was not found.

definitions:
  TaxFilingObject:
    type: object
    description: An individual Tax Filing record.
    properties:
      filingID:
        type: string
      year:
        type: string
      period:
        type: integer
      currency:
        type: string
      taxpayer:
        type: object

Swagger-UI with auth param text box

You can also add a security definition with type apiKey:

swagger: "2.0"
info:
  version: 1.0.0
  title: TaxBlaster
host: taxblaster.com
basePath: /api
schemes:
- http

securityDefinitions:
  api_key:
    type: apiKey
    name: api_key
    in: header
    description: Requests should pass an api_key header.
      
security: 
 - api_key: []
  
paths:

  /taxFilings/{id}:

    get:
      parameters:
      - name: id
        in: path
        description: ID of the requested TaxFiling
        required: true
        type: string

      responses:
        200:
          description: Successful response, with a representation of the Tax Filing.
          schema:
            $ref: "#/definitions/TaxFilingObject"
        404:
          description: The requested tax filing was not found.

definitions:
  TaxFilingObject:
    type: object
    description: An individual Tax Filing record.
    properties:
      filingID:
        type: string
      year:
        type: string
      period:
        type: integer
      currency:
        type: string
      taxpayer:
        type: object

The securityDefinitions object defines security schemes.

The security object (called "security requirements" in Swagger–OpenAPI), applies a security scheme to a given context. In our case, we're applying it to the entire API by declaring the security requirement a top level. We can optionally override it within individual path items and/or methods.

This would be the preferred way to specify your security scheme; and it replaces the header parameter from the first example. Unfortunately, Swagger-UI doesn't offer a text box to control this parameter, at least in my testing so far.

Solution 3 - Api

In ASP.NET Core 2 Web API, using Swashbuckle.AspNetCore package 2.1.0, implement a IDocumentFilter:

SwaggerSecurityRequirementsDocumentFilter.cs

using System.Collections.Generic;
using Swashbuckle.AspNetCore.Swagger;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace api.infrastructure.filters
{
    public class SwaggerSecurityRequirementsDocumentFilter : IDocumentFilter
    {
        public void Apply(SwaggerDocument document, DocumentFilterContext context)
        {
            document.Security = new List<IDictionary<string, IEnumerable<string>>>()
            {
                new Dictionary<string, IEnumerable<string>>()
                {
                    { "Bearer", new string[]{ } },
                    { "Basic", new string[]{ } },
                }
            };
        }
    }
}

In Startup.cs, configure a security definition and register the custom filter:

public void ConfigureServices(IServiceCollection services)
{
    services.AddSwaggerGen(c =>
    {
        // c.SwaggerDoc(.....

        c.AddSecurityDefinition("Bearer", new ApiKeyScheme()
        {
            Description = "Authorization header using the Bearer scheme",
            Name = "Authorization",
            In = "header"
        });

        c.DocumentFilter<SwaggerSecurityRequirementsDocumentFilter>();
    });
}

In Swagger UI, click on Authorize button and set value for token.

Window to set value

Result:

curl -X GET "http://localhost:5000/api/tenants" -H "accept: text/plain" -H "Authorization: Bearer ABCD123456"

Solution 4 - Api

Also it's possible to use attribute [FromHeader] for web methods parameters (or properties in a Model class) which should be sent in custom headers. Something like this:

[HttpGet]
public ActionResult Products([FromHeader(Name = "User-Identity")] string userIdentity)

At least it works fine for ASP.NET Core 2.1 and Swashbuckle.AspNetCore 2.5.0.

Solution 5 - Api

Here's a simpler answer for the ASP.NET Core Web Api/Swashbuckle combo, that doesn't require you to register any custom filters. Third time's a charm you know :).

Adding the code below to your Swagger config will cause the Authorize button to appear, allowing you to enter a bearer token to be sent for all requests. Don't forget to enter this token as Bearer <your token here> when asked.

Note that the code below will send the token for any and all requests and operations, which may or may not be what you want.


    services.AddSwaggerGen(c =>
    {
        //...

        c.AddSecurityDefinition("Bearer", new ApiKeyScheme()
        {
            Description = "JWT Authorization header using the Bearer scheme. Example: \"Authorization: Bearer {token}\"",
            Name = "Authorization",
            In = "header",
            Type = "apiKey"
        });
                
        c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>>
        {
            { "Bearer", new string[] { } }
        });

        //...
    }

Via this thread.

Solution 6 - Api

I ended up here because I was trying to conditionally add header parameters in Swagger UI, based on my own [Authentication] attribute I added to my API method. Following the hint that @Corcus listed in a comment, I was able to derive my solution, and hopefully it will help others.

Using Reflection, it's checking if the method nested down in apiDescription has the desired attribute (MyApiKeyAuthenticationAttribute, in my case). If it does, I can append my desired header parameters.

public void Apply(Operation operation, SchemaRegistry schemaRegistry, ApiDescription apiDescription) {
	if (operation.parameters == null)
		operation.parameters = new List<Parameter>();


	var attributes = ((System.Web.Http.Controllers.ReflectedHttpActionDescriptor)
		((apiDescription.ActionDescriptor).ActionBinding.ActionDescriptor)).MethodInfo
		.GetCustomAttributes(false);
	if(attributes != null && attributes.Any()) {
		if(attributes.Where(x => x.GetType() 
			== typeof(MyApiKeyAuthenticationAttribute)).Any()) {

			operation.parameters.Add(new Parameter {
				name = "MyApiKey",
				@in = "header",
				type = "string",
				description = "My API Key",
				required = true
			});
			operation.parameters.Add(new Parameter {
				name = "EID",
				@in = "header",
				type = "string",
				description = "Employee ID",
				required = true
			});
		}
	}

		
}

Solution 7 - Api

For those who use NSwag and need a custom header:

app.UseSwaggerUi3(typeof(Startup).GetTypeInfo().Assembly, settings =>
      {
          settings.GeneratorSettings.IsAspNetCore = true;
          settings.GeneratorSettings.OperationProcessors.Add(new OperationSecurityScopeProcessor("custom-auth"));

          settings.GeneratorSettings.DocumentProcessors.Add(
              new SecurityDefinitionAppender("custom-auth", new SwaggerSecurityScheme
                {
                    Type = SwaggerSecuritySchemeType.ApiKey,
                    Name = "header-name",
                    Description = "header description",
                    In = SwaggerSecurityApiKeyLocation.Header
                }));
        });            
    }

Swagger UI will then include an Authorize button.

Solution 8 - Api

Golang/go-swagger example: https://github.com/go-swagger/go-swagger/issues/1416

// swagger:parameters opid
type XRequestIdHeader struct {
	// in: header
	// required: true
	XRequestId string `json:"X-Request-Id"`
}

...
    // swagger:operation POST /endpoint/ opid
	// Parameters:
	// - $ref: #/parameters/XRequestIDHeader

Solution 9 - Api

Update for OpenAPI 3, library Swashbuckle.AspNetCore. Correct code sample is provifded by this source: https://codeburst.io/api-security-in-swagger-f2afff82fb8e

For use with JWT Bearer correct code is:

services.AddSwaggerGen(c =>
{
    // configure SwaggerDoc and others

    // add JWT Authentication
    var securityScheme = new OpenApiSecurityScheme
    {
        Name = "JWT Authentication",
        Description = "Enter JWT Bearer token **_only_**",
        In = ParameterLocation.Header,
        Type = SecuritySchemeType.Http,
        Scheme = "bearer", // must be lower case
        BearerFormat = "JWT",
        Reference = new OpenApiReference
        {
            Id = JwtBearerDefaults.AuthenticationScheme,
            Type = ReferenceType.SecurityScheme
        }
    };
    c.AddSecurityDefinition(securityScheme.Reference.Id, securityScheme);
    c.AddSecurityRequirement(new OpenApiSecurityRequirement
    {
        {securityScheme, new string[] { }}
    });
}

I've seen one article with similar code for OpenAPI 2 and lost many hours because that example missed Reference definition. This resulted that Swashbuckle generated incorrect definitions and missed to include Authorizeation header. So check carefully the OpenAPI version you use.

Solution 10 - Api

DISCLAIMER: this solution is not using Header.

If someone is looking for a lazy-lazy manner (also in WebApi), I'd suggest:

public YourResult Authorize([FromBody]BasicAuthCredentials credentials)

You are not getting from header, but at least you have an easy alternative. You can always check the object for null and fallback to header mechanism.

Solution 11 - Api

This is how I achieved it in .NET 6

public class AddCustomHeaderParameter 
    : IOperationFilter
{
    public void Apply(
        OpenApiOperation operation, 
        OperationFilterContext context)
    {
        if (operation.Parameters is null)
        {
            operation.Parameters = new List<OpenApiParameter>();
        }

        operation.Parameters.Add(new OpenApiParameter
        {
            Name = "Custom Header",
            In = ParameterLocation.Header,
            Description = "Custom Header description",
            Required = true,
        });
    }
}

And finally

services.AddSwaggerGen(c =>
        {
            c.OperationFilter<AddCustomHeaderParameter>();
        });

Solution 12 - Api

If you are working with Nest.js, it can be achieved by adding addBearerAuth() while setting up the swagger(probably in the main.ts).

...........

  const config = new DocumentBuilder()
    .setTitle('Your title')
    .setDescription('Your description')
    .setVersion('1.0')
    .addBearerAuth()   // Add here
    .build();

  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('api', app, document);

...........

With this added, we can pass in the Bearer token from the Swagger UI as:

Swagger documentation

PS: You have to use Authguard in respective controllers to protect your routes.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSergei BasharovView Question on Stackoverflow
Solution 1 - ApiShaTinView Answer on Stackoverflow
Solution 2 - ApiTed EpsteinView Answer on Stackoverflow
Solution 3 - ApiGeorge PaoliView Answer on Stackoverflow
Solution 4 - ApiVictor SharovatovView Answer on Stackoverflow
Solution 5 - ApiVlad IliescuView Answer on Stackoverflow
Solution 6 - ApiInbetweenWeekendsView Answer on Stackoverflow
Solution 7 - ApiOfirisView Answer on Stackoverflow
Solution 8 - ApiQiang LiView Answer on Stackoverflow
Solution 9 - ApiAlexey SukhanovView Answer on Stackoverflow
Solution 10 - ApiCesarView Answer on Stackoverflow
Solution 11 - ApiBen DView Answer on Stackoverflow
Solution 12 - ApiJohnView Answer on Stackoverflow