Friday, June 26, 2015
Customize Authentication Header in SwaggerUI using Swashbuckle

Swagger has quickly established itself as an important tool for building Web API’s for any platform. Swagger enables interactive documentation and client SDK generation/discoverability. One of the most frequently used Swagger tools is Swagger UI. Swagger UI provides automatically generated HTML assets that give you automatic documentation and even an online test tool. To see Swagger UI in action, check out their demo page.

Although Swagger/Swagger UI can be used for any platform, the Swashbuckle library makes integrating Swagger UI into a .NET Web API app a breeze. In fact, Azure API Apps specifically leverage Swagger via Swashbuckle to provide the metadata for Azure API apps.

Most of the out of the box features of Swagger work great. However, there are times when you need to customize this behavior. For example, by default Swagger UI gives you a textbox for for the “API key”. When you execute the request, it simply puts this API key into a query string variable called “api_key” as shown in the screen shot:

But what do you do if you need some other type of authentication? Perhaps you need Basic Auth or suppose the API key needs to be sent in an HTTP header rather than the query string.

Most of the online resources I found, suggest that you should simply replace the default web page by copying the original and making the changes you need. While it’s great to have this type of flexibility, the problem is that it makes it harder to keep up when new versions come out. You’d have to continually update your code (that you’ve now taken ownership of) each time a new version comes out.

What I want to do instead is to simply inject some JavaScript into the page to make this happen. This JavaScript needs to:

  • Add two textboxes to the page (one for username and one for password)
  • Remove/hide the existing textbox for API key
  • Set the Password Authorization (basic auth) header to use these values

Here are the steps to make that happen.

First, make sure the “Swashbuckle” and “Swashbuckle.Core” NuGet packages are added to your project. If you’re working in an Azure API app, they’ll already be added for you.

Next, add a new JavaScript file to your project. I’ll put this file in a folder called “CustomContent”:

Right-click this new JavaScript file and select “Properties”. Then change its “Build Action” to “Embedded Resource”.

Next, go to the SwaggerConfig.cs file that was added to your project when you added the Swashbuckle NuGet package. This file contains a ton of commented code – this is just to show you example configuration code that you can use. If you scroll down that file, you’ll see a commented method call to the InjectJavaScript() method. Right below that, I can now add this line of C# code:

   1:  c.InjectJavaScript(thisAssembly, "SwashbuckleCustomAuth.CustomContent.basic-auth.js");

Pay close attention to this string. The default namespace for my project happens to be “SwashbuckleCustomAuth”. Then I’ve put this JavaScript file in a folder called “CustomContent”. Finally, I give the name of the JS file. Make sure you’ve got this string correct so it will find the embedded resource properly.

Next, let’s have a look at the JavaScript code that we need to put in to basic-auth.js:

   1:  (function () {
   2:      $(function () {
   3:          var basicAuthUI =
   4:              '<div class="input"><input placeholder="username" id="input_username" name="username" type="text" size="10"/></div>' +
   5:              '<div class="input"><input placeholder="password" id="input_password" name="password" type="password" size="10"/></div>';
   6:          $(basicAuthUI).insertBefore('#api_selector div.input:last-child');
   7:          $("#input_apiKey").hide();
   9:          $('#input_username').change(addAuthorization);
  10:          $('#input_password').change(addAuthorization);
  11:      });
  13:      function addAuthorization() {
  14:          var username = $('#input_username').val();
  15:          var password = $('#input_password').val();
  16:          if (username && username.trim() != "" && password && password.trim() != "") {
  17:              var basicAuth = new SwaggerClient.PasswordAuthorization('basic', username, password);
  18:              window.swaggerUi.api.clientAuthorizations.add("basicAuth", basicAuth);
  19:              console.log("authorization added: username = " + username + ", password = " + password);
  20:          }
  21:      }
  22:  })();

jQuery is already part of the HTML page so we can leverage that here. I use JavaScript to create the two new textboxes I need – then I insert them as the last child of the “api_selector” form that contains these textboxes in the header. I then hide the default api key textbox since we won’t be using it. The next thing we need to ensure is that we’re setting the header correctly when the values in these textboxes change. For this we can use the SwaggerClient.PasswordAuthorization which is built into the Swagger JavaScript library. This code will ensure it’s added to the request:

In the screen shot above, I put in a username of “steve” and a password of “123”. This time when I invoke the request, you can see an Authorization header for Basic auth being sent in the HTTP request headers. Problem solved.

Alternatively, let’s say that instead of Basic Auth, you want the API key sent in the header rather than in the query string. Furthermore, let’s say you need that API header to be called “my-cool-api-key”. In that case, we don’t need to add any of our own textboxes but just repurpose the API key text box that is already there. We can add a new JavaScript file and make it an embedded resource in the exact same way that I’ve previously described. The JavaScript for that will look like this:

   1:  (function () {
   2:      $(function () {
   3:          $('#input_apiKey').off();
   4:          $('#input_apiKey').on('change', function () {
   5:              var key = this.value;
   6:              if (key && key.trim() !== '') {
   7:                  swaggerUi.api.clientAuthorizations.add("key", new SwaggerClient.ApiKeyAuthorization("my-cool-api-key", key, "header"));
   8:              }
   9:          });
  10:      });
  11:  })();

One other point that can sometimes lead to confusion. You might notice that the Swashbuckle configuration contains methods like this:

   1:  c.BasicAuth("basic").Description("Basic HTTP Authentication");

At first glance you might think/hope that will make the UI do the Basic Authentication for you – but it doesn’t. That simply changes the metadata that comes out of the Swagger schema that *informs* the user what type of authentication is being used. But if you actually want the Swagger UI to correctly execute the appropriate authentication scheme, follow the steps in this blog post if you’re working in .NET projects.

A sample solution containing these techniques (minus the *actual* authentication) can be downloaded here.

Posted On Friday, June 26, 2015 4:30 PM | Comments (0)

View Steve Michelotti's profile on LinkedIn

profile for Steve Michelotti at Stack Overflow, Q&A for professional and enthusiast programmers

Google My Blog

Tag Cloud