21

I am using swagger with servicestack but I am getting a 401 unauthorised error from my /resources URL becuase it requires an API key.

Unless I'm mistaken, according to the documentation I should set supportHeaderParams to true as well as the apiKeyName and apiKey value in the JSON parameters when initializing Swagger from my html page.

I was then expecting to see my API key in the http request headers, but it is still being appended to the URL and not in the headers collection.

Here is the code that initialises Swagger in my HTML page:

 window.swaggerUi = new SwaggerUi({
            discoveryUrl: "http://pathtomyservice.com/resources",
                headers: { "testheader" : "123" },
                apiKey: "123",
                apiKeyName: "Api-Key",
                dom_id:"swagger-ui-container",
                supportHeaderParams: true,
                supportedSubmitMethods: ['get', 'post', 'put', 'delete'],
                onComplete: function(swaggerApi, swaggerUi){
                    if(console) {
                        console.log("Loaded SwaggerUI");
                        console.log(swaggerApi);
                        console.log(swaggerUi);
                    }
                  $('pre code').each(function(i, e) {hljs.highlightBlock(e)});
                },
                onFailure: function(data) {
                    if(console) {
                        console.log("Unable to Load SwaggerUI");
                        console.log(data);
                    }
                },
                docExpansion: "none"
            });

Unfortunately I get no headers at all, no 'Api-Key' or 'testheader'.

Hunsu
  • 3,281
  • 7
  • 29
  • 64
Rob Bird
  • 3,764
  • 2
  • 28
  • 38

3 Answers3

26

I think that it might be a bug in swagger ui.

As a workaround, I added the following in in the swagger index.html file.

$(function () {
   $.ajaxSetup({
       beforeSend: function (jqXHR, settings) {
           jqXHR.setRequestHeader("YourApiKeyHeader", $("#input_apiKey").val());
       }
   });
});

Hope this helps,

gsimoes
  • 1,011
  • 11
  • 12
  • You might want to look at the new version of swagger-ui - 1.3. _supportHeaderParams_ isn't needed anymore. – Eyal Aug 30 '13 at 08:58
  • How to set #input_apiKey value for dynamically generated key?. I am struggling for that from 2 days. Please help me out. Also posted question in S.O. http://stackoverflow.com/questions/33435286/swagger-ui-passing-authentication-token-to-api-call-in-header – Java P Nov 02 '15 at 11:43
  • This adds the value to the header but it doesn't remove it from the url. I'd like to add my own authentication header using the api_key entered but I don't want the api_key sent in get or post. Still working out this solution myself but I'm curious if anyone here worked that out. – HarryTuttle Jan 27 '16 at 21:12
20

In swagger-ui 2.0 or greater, this is trivial:

https://github.com/wordnik/swagger-ui#header-parameters

// add a new ApiKeyAuthorization when the api-key changes in the ui.
$('#input_apiKey').change(function() {
  var key = $('#input_apiKey')[0].value;
  if(key && key.trim() != "") {
    window.authorizations.add("key", new ApiKeyAuthorization("api_key", key, "header"));
  }
})

This is also much more extensible and supports custom authentication mechanisms.

fehguy
  • 6,724
  • 25
  • 23
  • Thanks for the update! I didn't know there was a v2.0 released, I will definitely take a look. Cheers – Rob Bird Sep 05 '13 at 19:47
  • How to set #input_apiKey value for dynamically generated key?. I am struggling for that from 2 days. Please help me out. Also Posted question in S.O. http://stackoverflow.com/questions/33435286/swagger-ui-passing-authentication-token-to-api-call-in-header – Java P Nov 02 '15 at 11:43
  • 2
    This doesn't work still. Any addition to headers with window.authorizations.add() or window.swaggerUi.api.clientAuthorizations.add() does not have any effect and Authorisation header is not added. – mixdev Jan 11 '16 at 11:26
  • I'm quite positive that it works. Can you please share how you're testing it? – fehguy Jan 12 '16 at 17:25
  • @JavaP Once you have the token you can set it in api_key on swaggerUI home page. So again if a new token is generated then you have to set it in home page one more time. But one suggestion I can give, Swagger UI source code is available so you can customize as per your requirement. Definitely you can try to whats your requirement is. – Nasruddin Feb 24 '16 at 11:22
  • for me its also not working, is there something i need to define in my API yaml for server? – Gobliins Mar 16 '16 at 12:48
  • You have to declare what needs to be authenticated inside your swagger definition. If it's everything, then there should be a `security` element at the top-level. In addition, there was a recent update to swagger-ui which dynamically shows authentication mechanisms. See a demo at http://petstore.swagger.io or grab from https://github.com/swagger-api/swagger-ui in the master branch – fehguy Mar 16 '16 at 14:39
  • Is there a section for "header-parameters" in the `swagger-ui` github page? I don't see it. The link should be corrected. – Sonny Mar 26 '17 at 20:23
1

you can try this

(function () {
    $(function () {
        var basicAuthUI =
                '<div class="input"><input placeholder="username" id="input_username" name="username" type="text" size="10"/></div>' +
                '<div class="input"><input placeholder="password" id="input_password" name="password" type="password" size="10"/></div>';
        $(basicAuthUI).insertBefore('#api_selector div.input:last-child');
        $("#input_apiKey").hide();

        $('#input_username').change(addAuthorization);
        $('#input_password').change(addAuthorization);
    });

    function addAuthorization() {
        SwaggerApi.supportHeaderParams = true;
        SwaggerApi.headers = {"authentication": "test"};
        var username = $('#input_username').val();
        var password = $('#input_password').val();
        if (username && username.trim() != "" && password && password.trim() != "") {
            var basicAuth = new SwaggerClient.PasswordAuthorization('basic', username, password);
            window.swaggerUi.api.clientAuthorizations.add("basicAuth", basicAuth);
            console.log("authorization added: username = " + username + ", password = " + password);
        }
    }
})();
Tuan Minh
  • 11
  • 4