10

I am using the library Swashbuckle. Currently there is no stackoverflow tag for it.

I don't quite understand the documentation here: https://github.com/domaindrivendev/Swashbuckle/blob/master/README.md

The section titled "Describing Security/Authorization Schemes" mentions a piece of code

   c.ApiKey("apiKey")
                .Description("API Key Authentication")
                .Name("apiKey")
                .In("header");

However when I include this nothing happens. I would also like this to only appear on certain API methods. It does mention

"need to be coupled with a corresponding "security" property at the document "

But I don't understand this.

Can anyone explain?

Cœur
  • 37,241
  • 25
  • 195
  • 267
LivingOnACloud
  • 1,151
  • 1
  • 11
  • 20

3 Answers3

5

I had the same question and solve it this way:

At SwaggerConfig:

var applyApiKeySecurity = new ApplyApiKeySecurity(
    key: "ServiceBusToken",
    name: "Authorization",
    description: "Service Bus Token, e.g. 'SharedAccessSignature sr=...&sig=...&se=...&skn=...'",
    @in: "header"
);
applyApiKeySecurity.Apply(c);

ApplyApiKeySecurity:

public class ApplyApiKeySecurity : IDocumentFilter, IOperationFilter
{
    public ApplyApiKeySecurity(string key, string name, string description, string @in)
    {
        Key = key;
        Name = name;
        Description = description;
        In = @in;
    }

    public string Description { get; private set; }

    public string In { get; private set; }

    public string Key { get; private set; }

    public string Name { get; private set; }

    public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, System.Web.Http.Description.IApiExplorer apiExplorer)
    {
        IList<IDictionary<string, IEnumerable<string>>> security = new List<IDictionary<string, IEnumerable<string>>>();
        security.Add(new Dictionary<string, IEnumerable<string>> {
            {Key, new string[0]}
        });

        swaggerDoc.security = security;
    }

    public void Apply(Operation operation, SchemaRegistry schemaRegistry, System.Web.Http.Description.ApiDescription apiDescription)
    {
        operation.parameters = operation.parameters ?? new List<Parameter>();
        operation.parameters.Add(new Parameter
        {
            name = Name,
            description = Description,
            @in = In,
            required = true,
            type = "string"
        });
    }

    public void Apply(Swashbuckle.Application.SwaggerDocsConfig c)
    {
        c.ApiKey(Key)
            .Name(Name)
            .Description(Description)
            .In(In);
        c.DocumentFilter(() => this);
        c.OperationFilter(() => this);
    }
}

Then the swagger file has the security definiton:

"securityDefinitions":{  
  "ServiceBusToken":{  
     "type":"apiKey",
     "description":"Service Bus Token, e.g. 'SharedAccessSignature sr=...&sig=...&se=...&skn=...'",
     "name":"Authorization",
     "in":"header"
  }
}

Applied to all operations at document level:

"security":[  
  {  
     "ServiceBusToken":[]
  }
]

And all operations have the header parameter assigned:

"parameters":[  
   {  
      "name":"Authorization",
      "in":"header",
      "description":"Service Bus Token, e.g. 'SharedAccessSignature sr=...&sig=...&se=...&skn=...'",
      "required":true,
      "type":"string"
   }
]
Larry
  • 487
  • 4
  • 8
2

Swashbuckle maintainer recommends us to provide a custom index.html to do this because he will remove these configurations in the next major version. See this issue.

Provide your own "index" file

Use the CustomAsset option to instruct Swashbuckle to return your version instead of the default when a request is made for "index". As with all custom content, the file must be included in your project as an "Embedded Resource", and then the resource's "Logical Name" is passed to the method as shown below. See Injecting Custom Content for step by step instructions.

For compatibility, you should base your custom "index.html" off this version.

httpConfiguration
    .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API"))
    .EnableSwaggerUi(c =>
        {
            c.CustomAsset("index", yourAssembly, "YourWebApiProject.SwaggerExtensions.index.html");
        });

In the index.html you will want to change the method below to something like this:

function addApiKeyAuthorization(){
    var key = encodeURIComponent($('#input_apiKey')[0].value);
    if(key && key.trim() != "") {
        var apiKeyAuth = new SwaggerClient.ApiKeyAuthorization("sessionId", key, "header");
        window.swaggerUi.api.clientAuthorizations.add("sessionId", apiKeyAuth);
        log("added key " + key);
    }
}
Akira Yamamoto
  • 4,685
  • 4
  • 42
  • 43
  • It feels like a hack compared to how I configured everything else – LivingOnACloud Aug 28 '15 at 06:45
  • Sure. Not pretty. I would prefer to use the configuration you showed us on your question but the maintainer will remove it... :-( and it also does not work because of a bug. – Akira Yamamoto Aug 29 '15 at 15:07
  • 1
    Use InjectJavaScript should be a better solution. See this issue thread: https://github.com/domaindrivendev/Swashbuckle/issues/222 I use this approach to add a bearer token for authorization in http header. – Johnny Qian Nov 08 '15 at 17:50
  • Cool! This way we don't need to replace the entire index file. Thanks! – Akira Yamamoto Nov 09 '15 at 20:26
0
        config.EnableSwagger(c =>
        {
            c.SingleApiVersion("v1", "TestApiWithToken");

            c.ApiKey("Token")
            .Description("Filling bearer token here")
            .Name("Authorization")
            .In("header");
        })
        .EnableSwaggerUi(c =>
        {
            c.EnableApiKeySupport("Authorization", "header");
        });
Roy Liu
  • 51
  • 3