How to send custom headers with requests in Swagger UI?
Asked Answered
W

16

153

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?

Woodley answered 16/12, 2016 at 9:1 Comment(0)
T
93

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.

Toy answered 16/12, 2016 at 14:43 Comment(2)
I am defining the parameters in the python module that defines endpoints using models which then I use RequestParse to add input fields in the swagger documentation as well. How and where this text file is to add ` - name: auth` ?Arsine
@Ted, there isn't a way we can provide a custom json(object) type information in openapi2.0? this attempt fails to compileTwyla
N
81

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);
        });
}
Nationality answered 13/4, 2017 at 5:0 Comment(6)
Hi thanks for sharing this, it's just what i needed. Is there a way to disable it for certain API methods? For instance the User Login one would not need that header passing as its returning the Auth token. This add's the 'MyHeaderField' to all the API methods Swagger documents.Calcine
@NeilHodges did you figure this out. I am even looking for it.Bareilly
@gee'K'iran You can selectively apply the functionality by inspecting the operation and apiDescription parameters and choosing to add the header or not.Ginter
Thank you for not including namespaces.Clubbable
I tried this. The customer header comes under Results View of httpContext.Request.Headers resultset but when I do var key = httpContext.Request.Headers.Where(z => z.Key == "CUSTOMKEY").FirstOrDefault(); I get key as [null,null]. Any ideas?Bishopric
@NeilHodges you can use the principles in this answer https://mcmap.net/q/159966/-how-to-check-of-an-action-allowes-anonymous-access-or-if-only-authorized to add an operation filter to check if the method has the [AllowAnonymous] attribute, and does not have the [Authorize] attributeJasper
L
24

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"
Lovering answered 28/2, 2018 at 17:35 Comment(2)
Which swagger version is it? Here in swagger 2.4.0 can't find the Authorize button.Infantryman
I also struggled with this at first. Apparently the open api spec needs to support the button. E.g. how PostgREST added a feature to support the button - postgrest.org/en/stable/releases/v10.0.0.html#openapi Now I just need to understand how swagger can refresh the docs once the Authorization token is set.Sandoval
S
21

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.

Sticktight answered 31/7, 2018 at 7:40 Comment(7)
This only works with MVC and not Web Api solution (at least I think so since it failed on my Web Api solution)Nephralgia
@bleh10 any details why it fails for your solution? For my Web API project it works just fine.Sticktight
Not sure why, it forced me to add the mvc library and when I did VS got confused, Ill recheck tomorrow since I'm not at work today and will add the error that I faced!Nephralgia
I stand corrected, I just tried it again and it worked, the only issue is that now I have to add "System.Web.Http." before HttpGET and route and FromBody which is kinda annoying but the best solution so far! Edit: An even better solution (not sure why I didnt think of it before) so I dont re edit all of my controllers is to add Microsoft.AspNetCore.Mvc. before FromHeader and now everything is working!Nephralgia
If you could copy your answer here I would tick it as the answer to my question (only if you want!)Nephralgia
Regarding adding "System.Web.Http." before HttpGET and route and FromBody - you can use "using" directive for that namespace to avoid this duplicate code. So just add using System.Web.Http; at the beginning of file where your controller is defined.Sticktight
Simple & concise! Thanks!Ibnsina
G
18

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>();
        });
Gracious answered 24/3, 2022 at 16:45 Comment(0)
S
5

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.

Stomach answered 25/9, 2018 at 8:42 Comment(0)
P
5

Just updating this for Asp.Net Core 6 web api and Swashbuckle.AspNetCore 6.4.0. It was surprisingly easy. In my case the header is required for all action methods so I have Required true.

One, create a Swashbuckle.AspNetCore.SwaggerGen.IOperationFilter:

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

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

Two, tell Swagger to use it when you are configuring services:

builder.Services.AddSwaggerGen(config =>
                {
                    //this causes Swagger to add an input so you can to add the value to header when you are executing an api method.
                    config.OperationFilter<IMyCustomFilter>();
                });

Three, invoke Swagger as usual:

        var app = builder.Build();

        if (app.Environment.IsDevelopment())
        {
            app.UseSwagger();
            app.UseSwaggerUI();
        }
Popgun answered 22/11, 2022 at 16:56 Comment(0)
A
4

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.

Airway answered 30/3, 2022 at 5:54 Comment(2)
In my case I have a black lock that opens authorization form.Rame
How do i add this in the YAMLEncrust
A
3

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.

Aestivate answered 7/5, 2018 at 19:56 Comment(0)
R
2

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


}
Rosenblast answered 13/2, 2018 at 15:54 Comment(1)
For those who are trying with API Key .Net core 2.1 c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> { { "ApiKeyAuth", new string[0] } }); #49909077Herriott
K
2

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.

Kendall answered 9/10, 2021 at 6:44 Comment(0)
B
1

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
Bellringer answered 9/7, 2019 at 19:32 Comment(0)
F
1

Suppose you are creating your documentation from your controller class directly instead of using the OpenAPI3 or Swagger2 yaml spec file. In that case, your controller endpoint methods must also include the parameters for the headers you want to see in swagger-ui. The header parameter(s) in your controller endpoint methods will automatically retrieve the header values passed in the request. It will also make swagger-ui to show input for it as an editable textbox.

For instance, let's say you have a controller endpoint defined as:

public ResponseEntity taxFilings(@PathVariable(value = "id") String id) {
   //some codes to do
}

Refactor the method definition this way:

public ResponseEntity taxFilings(@PathVariable(value = "id") String id, @RequestHeader(value = "auth") String auth) {
   //some codes to do
}

Your endpoint method implementation doesn't have to use the header parameter; the header passed in the HTTP request will still be useful wherever you have a need for it e.g. filters and security classes. The only reason why it's been passed in the endpoints method param is to make it visible in swagger-ui since swagger looks towards controller classes on how endpoints are defined and consumed.

Fuhrman answered 31/7, 2023 at 13:28 Comment(0)
H
0

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.

Hen answered 29/7, 2018 at 2:4 Comment(0)
S
0

In Feathers Swagger, to show the Authorize button on the top right in this case for BearerAuth, your config declaration must be done as such:

{
  ...config, // other config parameters
  specs: {
    info: {
      title: 'My API',
      description: 'My API Documentation',
      version: '2.0',
    },
    components: {
      securityDefinitions: {
        BasicAuth: {
          type: 'basic'
        },
        BearerAuth: {
          type: "http",
          scheme: "bearer",
          bearerFormat: "JWT"
        }
      },
    },
    security: {
      BearerAuth: []
    },
  },
}

Result enter image description here

Serotonin answered 13/10, 2022 at 10:29 Comment(0)
C
0

Here's an example with Java and Swagger 1.5.19 to include an editable text box in Swagger UI for the Authorization header:

@GET
@Path("something")
@Produces(MediaType.APPLICATION_JSON)
@ApiImplicitParams({
  @ApiImplicitParam(name = "Authorization", value = "Bearer Token", required = true, dataType = "string", paramType = "header", example = "Bearer <token string here>")
})
@ApiOperation(value = "Operation Name")
public Response getSomething(@Context HttpServletRequest request) {
    String token = request.getHeader("Authorization");
    // do something
    return Response.ok().build();
}

The important part is using @ApiImplicitParams along with one or more @ApiImplicitParam to include your header name.

Crossarm answered 1/11, 2023 at 1:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.