6

I have a .NET Core 2.x project which integrates Swagger and Swashbuckle v4.x. And it all works really well.

However, now I need to append a query string to every GET that is fired by Swagger in the form of www.foo.com/myendpoint?authorization=APIKEY. To that end, I have the following in Startup.ConfigureServices:

services.AddSwaggerGen(c => {
  c.SwaggerDoc("v1", new Info { Title = "My API", Version = "v1" });

  c.AddSecurityDefinition("api key", new ApiKeyScheme() {
      Description = "Authorization query string expects API key",
      In = "query",
      Name = "authorization",
      Type = "apiKey"
  });
}); 

When I fire up swagger, it does present me with a dialog box and successfully accepts it when I enter the API key. However, all the API calls still go out without the query string.

What am I missing?

enter image description here

AngryHacker
  • 59,598
  • 102
  • 325
  • 594
  • 1
    What happens if you add `c.AddSecurityRequirement(new Dictionary> { { "api key", new [] {} }};` after adding the definition? This should indicate to swagger that all operations should go through that definition. – Jonathon Chase Jun 11 '19 at 00:56
  • @JonathonChase That did the trick, thank you sir! – AngryHacker Jun 11 '19 at 01:17

1 Answers1

7

With Swashbuckle in particular, (NSwag has it's own means of registering authorization flows) it's not enough to just define the security definition, you also need to register which operations that use it.

Since you want to append the api-key to all operations, your use case is pretty straight forward: simply register the security requirement for your definition, which you can do so like this:

c.AddSecurityRequirement(new Dictionary<string, IEnumerable<string>> { { "api key", new[] {} } };

You can read more on how to define, customize, and register different authorization schemes for your operations here.

And for the upcoming v5 of Swashbuckle, the following code could be used:

c.AddSecurityDefinition("api key", new OpenApiSecurityScheme {
    Type = SecuritySchemeType.ApiKey,
    In = ParameterLocation.Query,
    Name = "authorization",
    Description = "Authorization query string expects API key"
});

var key = new OpenApiSecurityScheme() { Name = "api key"};
var requirement = new OpenApiSecurityRequirement {
    { key, new List<string>() }
};
c.AddSecurityRequirement(requirement);
AngryHacker
  • 59,598
  • 102
  • 325
  • 594
Jonathon Chase
  • 9,396
  • 21
  • 39
  • Do you know by chance the syntax for the new v5 of Swashbuckle? It doesn't seem to have the `ApiKeyScheme` class at all. Looks like it's been upgraded to a `Microsoft.OpenApi.Models.OpenApiSecurityScheme` library. – AngryHacker Jun 11 '19 at 01:33
  • @AngryHacker I haven't, I've been using the NSwag wrappers recently. I don't believe you need to change too much though. I believe the ApiKey is now an AuthorizationCode, and you would define it as the in-use Flow. – Jonathon Chase Jun 11 '19 at 01:40
  • 2
    I figured it out. Added your answer. – AngryHacker Jun 11 '19 at 01:45
  • 1
    For future readers, for Swashbuckle AspNetCore v6.2.3, I had to change `new OpenApiSecurityScheme() { Name = "api key"}` to be `new OpenApiSecurityScheme { Reference = new OpenApiReference { Type = ReferenceType.SecurityScheme, Id="api key"}}` (or in my case, a constant in place of "api key") as per [the readme](https://github.com/domaindrivendev/Swashbuckle.AspNetCore#add-security-definitions-and-requirements). – CJC Mar 02 '23 at 12:06