Skip to content

Instantly share code, notes, and snippets.

@darraghoriordan
Created September 19, 2017 06:56
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save darraghoriordan/338b60eaac3693a24b67ad5f26b79263 to your computer and use it in GitHub Desktop.
Save darraghoriordan/338b60eaac3693a24b67ad5f26b79263 to your computer and use it in GitHub Desktop.
Adding custom hmac auth to swagger ui
(function () {
$(function () {
/*I add the ui elements I need here. I thought it would be better put them in here at runtime rather than hard code them in the index.html in case the index.html from my version of swashbuckle is made obsolete in a future version of the package. */
var hmacAuthUi =
'
<div class="input"><label for="input_api_username">Api Username: </label><input placeholder="Api Username" id="input_api_username" name="input_api_username" type="text" size="20"></div>
' +
'
<div class="input"><label for="input_api_hmackey">Api Key: </label><input placeholder="ApiKey" id="input_api_hmackey" name="input_api_hmackey" type="text" size="20"></div>
' +
'
<div class="input"><label for="input_customer_api_username">Customer Username: </label><input placeholder="User Name" id="input_customer_api_username" name="input_customer_api_username" type="text" size="20"></div>
';
$(hmacAuthUi).insertBefore('#api_selector div.input:last-child');
/*Hide the standard controls provided by the swagger-ui index.html. We won't need them. */
$("#input_apiKey").hide();
$("#input_baseUrl").hide();
/* This just sets a default value for this username field so we don;t have to enter everytime in test*/
$("#input_api_username").val("testUser");
var CustomHmacRequestSigner = function (name) {
this.name = name;
};
/* This is the main hashing function. It takes the HTTP request context and uses various parts of that request to create a hash */
function customHash(obj, datestamp, apiKey) {
var stringToSign = obj.method + obj.url + datestamp;
if (obj.body) {
var bodyUtf8 = CryptoJS.enc.Utf8.parse(obj.body);
console.log('utf8 of body: ' + bodyUtf8);
var bodysha256 = CryptoJS.SHA256(bodyUtf8);
console.log('sha256 of utf8 of body: ' + bodysha256);
var bodybase64Hash = CryptoJS.enc.Base64.stringify(bodysha256);
console.log('base 64 of body hash: ' + bodybase64Hash);
stringToSign += bodybase64Hash;
}
console.log('raw string to sign: ' + stringToSign);
var utf8StringToSign = CryptoJS.enc.Utf8.parse(stringToSign);
console.log('utf8 string to sign: ' + utf8StringToSign);
var utf8OfApiKey = CryptoJS.enc.Utf8.parse(apiKey);
console.log('utf8 api key: ' + utf8OfApiKey);
var hash = CryptoJS.HmacSHA1(utf8StringToSign, utf8OfApiKey);
console.log('hmac sha1 hash of string with key: ' + hash);
var base64Hash = CryptoJS.enc.Base64.stringify(hash);
console.log('base 64 of hash: ' + base64Hash);
return base64Hash;
}
/* This is the function that is called every time the ui tries to make a request. We take the username and key that the user has entered in to the form fields. We hash the request with those values and add some new headers. This is where you can do any authentication you might want to do. */
CustomHmacRequestSigner.prototype.apply = function (obj, authorizations) {
var datestamp = moment().toISOString();
var hashFunction = customHash;
var apiKey = $('#input_api_hmackey').val();
var customerUserName = $('#input_api_customer_username').val();
var apiUserName = $('#input_api_username').val();
var hash = hashFunction(obj, datestamp, apiKey);
obj.headers['X-Custom-Identity'] = customerUserName;
obj.headers['X-Custom-Authorization'] = apiUserName + ":" + hash;
obj.headers['X-Custom-Timestamp'] = datestamp;
return true;
};
authorizations.add("custom-hmac-authorization", new CustomHmacRequestSigner());
});
})();
@acds
Copy link

acds commented Apr 12, 2019

Hi @darraghoriordan - in trying to understand what you have done here (great BTW - v close to what I need) I seem get an issue with line #71 - with a Javascript error of `Can't find variable: authorizations.

I assume I'm miting something in my swagger/swashbuckle setup ?

Any hints or suggestions appreciated appreciated!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment