Skip to content

Instantly share code, notes, and snippets.

@bymaximus
Forked from darraghoriordan/swhmac.groovy
Created December 13, 2023 13:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bymaximus/98c76a8aac1a1997cba2f9683ecc5d3d to your computer and use it in GitHub Desktop.
Save bymaximus/98c76a8aac1a1997cba2f9683ecc5d3d 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());
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment