API key in header with swashbuckle
Asked Answered
R

4

24

I want to do API key based authentication on a WebAPI project with Swashbuckle (swagger for .net).

I have configured swashbuckle as below:

config
    .EnableSwagger(c =>
    {
        c.ApiKey("apiKey")
            .Description("API Key Authentication")
            .Name("X-ApiKey")
            .In("header");
        c.SingleApiVersion("v1", "My API");

    })
    .EnableSwaggerUi();

(see https://github.com/domaindrivendev/Swashbuckle#describing-securityauthorization-schemes)

It appears to create the swagger file I expect:

   "securityDefinitions": {
      "apiKey": {
        "type": "apiKey",
        "description": "API Key Authentication",
        "name": "X-ApiKey",
        "in": "header"
      }
    }

But when I go to the UI and 'Try it out' it tries to put the API key into the query string (which I think is the default behavior) instead of the headers.

eg:

curl -X POST --header 'Accept: application/json' 'http://localhost:63563/api/MyMethod?api_key=key'

How can I get swagger to use put the API key in the header instead of the query string?

Ratite answered 2/5, 2016 at 5:14 Comment(0)
N
34

Update 2021-09-15:

As already noted in Justin Greywolf's comment.

The "In" and "Type" properties have been changed from a string to the ParameterLocation and SecuritySchemeType enums:

services.AddSwaggerGen(c =>{
    c.SwaggerDoc("v1", new Info { Title = "[anything]", Version = "v1" });
    c.AddSecurityDefinition("[auth scheme: same name as defined for asp.net]", new ApiKeyScheme() {
        In = ParameterLocation.Header,
        Name = "X-API-KEY", //header with api key
        Type = SecuritySchemeType.ApiKey,
    });
});

Update 2019-04-10:

The paradigm has shifted to accommodate security definitions in the generated swagger.json

Source https://github.com/domaindrivendev/Swashbuckle.AspNetCore#add-security-definitions-and-requirements

services.AddSwaggerGen(c =>{
    c.SwaggerDoc("v1", new Info { Title = "[anything]", Version = "v1" });
    c.AddSecurityDefinition("[auth scheme: same name as defined for asp.net]", new ApiKeyScheme() {
        In = "header", // where to find apiKey, probably in a header
        Name = "X-API-KEY", //header with api key
        Type = "apiKey", // this value is always "apiKey"
    });

});

Original Answer

Check it out:

config
    .EnableSwagger(c =>
    {
        c.ApiKey("apiKey")
            .Description("API Key Authentication")
            .Name("X-ApiKey")
            .In("header");
        c.SingleApiVersion("v1", "My API");

    })
    .EnableSwaggerUi(c => {
        c.EnableApiKeySupport("X-ApiKey", "header");
    })
Niveous answered 7/4, 2017 at 15:47 Comment(5)
This worked for me. When adjusting the swagger configuration settings be sure to run the iisreset command (if you are using full IIS). The configuration sometimes get cached and you won't see the changes.Hambley
@keith Looks like this has changed again in Swashbuckle 5.x this has changed again. c.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme { Description = "ApiKey must appear in header", Type = SecuritySchemeType.ApiKey, Name = "X-ApiKey", In = ParameterLocation.Header });Bract
I also forgot to add the Security Requirement with AddSecurityRequirement as explained here: github.com/domaindrivendev/… , maybe it helps someoneClambake
This isn't working - I've tried everything and ended up hacking a required Header parameter with the same name of the apikey header. I now need to paste it in manually for every method. SwaggerUI still doesn't send it after submitting it.Bronder
@SkyeHoefling please update your answer with sample from mine https://mcmap.net/q/547265/-api-key-in-header-with-swashbuckle. Your sample not works currently.Celaeno
N
8

Incase anyone stumbles on this question, this is what I had to do:

(Borrowed from another thread I cannot find again, soz)

builder.Services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "ServiceName", Version = "1" });
    c.AddSecurityDefinition("ApiKey", new OpenApiSecurityScheme
{
    Name = "x-api-key",
    In = ParameterLocation.Header,
    Type = SecuritySchemeType.ApiKey,
    Description = "Authorization by x-api-key inside request's header",
    Scheme = "ApiKeyScheme"
});

var key = new OpenApiSecurityScheme()
{
    Reference = new OpenApiReference
    {
        Type = ReferenceType.SecurityScheme,
        Id = "ApiKey"
    },
    In = ParameterLocation.Header
};

var requirement = new OpenApiSecurityRequirement{{ key, new List<string>()}};

c.AddSecurityRequirement(requirement);
});
Northumbria answered 19/10, 2022 at 6:24 Comment(6)
This doesnt work in version 6.5 of Swashbuckle :(Bronder
@MartinKirk I just upgraded from 6.4 => 6.5 now and it still works. Did you add [ApiKey] Attributes to you controllers/methods? If not look up ApiKeyAttributeNorthumbria
Where does that ApiKeyAttribute come from ? it doesnt seem to come from the Swashbuckle packages. All i can find is a custom Attribute. Currently im using AddRequiredHeaderParameter in order to at least ask for the Header in each SwaggerUI call. The problem is that SwaggerUI doesnt copy the ApiKey into the Header.Bronder
@MartinKirk look up "Secure ASP.NET Core Web API using API Key Authentication" on the googly thingy.Northumbria
Look at the OP question. He specifically asks that SwaggerUI sends the API Key using the Header. But it does not ! I've myself created a SwaggerUI page that lets you login, setting the API Key. But that key is never sent from SwaggerUI to the API.Bronder
@MartinKirk I use 6.5 now in my production-set webapi proxyservice used by 3 different systems, if I don't enter a key in swagger-ui it fails. If I enter key under the lock-item it works using the steps I have mentioned above.Northumbria
W
3

You'll have to inject a custom index.html based on the original (as described here) and change the following line in the function addApiKeyAuthorization:

var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("X-ApiKey", key, "header");
Woo answered 2/5, 2016 at 20:46 Comment(1)
This sucks as a solution but it does seem like the only way to do it :(Ratite
C
0

For version 6.6.2 there is a solution from this github comment.

  c.AddSecurityDefinition("ApiKeyHeader", new OpenApiSecurityScheme()
  {
      Name = "x-api-key",
      In = ParameterLocation.Header,
      Type = SecuritySchemeType.ApiKey,
      Description = "Authorization by x-api-key inside request's header",
  });
  c.AddSecurityRequirement(new OpenApiSecurityRequirement{
      {
          new OpenApiSecurityScheme
          {
              Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id = "ApiKeyHeader" }
          },
          new string[] {}
      }
  });
Celaeno answered 22/7, 2024 at 13:58 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.