23

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?

undefined
  • 33,537
  • 22
  • 129
  • 198

3 Answers3

32

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");
    })
Sander Declerck
  • 2,455
  • 4
  • 28
  • 38
Keith Ripley
  • 1,020
  • 1
  • 10
  • 18
  • 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. – Skye Hoefling Jul 27 '17 at 17:58
  • 17
    @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 }); – Justin Greywolf Jul 26 '19 at 19:04
  • 2
    I also forgot to add the Security Requirement with AddSecurityRequirement as explained here: https://github.com/domaindrivendev/Swashbuckle.AspNetCore#add-security-definitions-and-requirements , maybe it helps someone – Andreas Jagiella May 12 '22 at 09:12
  • 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. – Martin Kirk Apr 27 '23 at 06:25
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");
venerik
  • 5,766
  • 2
  • 33
  • 43
3

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);
});
Terje Solem
  • 816
  • 1
  • 10
  • 25
  • This doesnt work in version 6.5 of Swashbuckle :( – Martin Kirk Apr 21 '23 at 10:53
  • @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 ApiKeyAttribute – Terje Solem Apr 24 '23 at 10:25
  • 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. – Martin Kirk Apr 25 '23 at 13:46
  • @MartinKirk look up "Secure ASP.NET Core Web API using API Key Authentication" on the googly thingy. – Terje Solem May 02 '23 at 07:44
  • 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. – Martin Kirk May 02 '23 at 10:50
  • @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. – Terje Solem May 22 '23 at 11:32