cancel
Showing results for 
Search instead for 
Did you mean: 

HTTP Signature - Authentication Failed

Hello Community - I am wondering is there are any logs or anything I can look at to why my Authentication Failed? I am getting this response below...

{"response":{"rmsg":"Authentication Failed"}}

My calls from postman are working and redoing all of the scripting to generate the header values are all the same so I am confused to why postman is working and our VueJS application is not?

We are using Axios to make our post request. I will also mention I am running chrome with all security disabled to get past CORS issues from localhost. So not sure if that is the issue in it self but the API seems to behave as if that isn't the problem, if I remove a header value like date then it tells me it failed because the date isn't present. 

Does anyone see any glaring issues in my code below. 

Our variables 

// Cybersource variables 
const requestHost = 'apitest.cybersource.com';
const merchantId = '{redacted}';
const merchantKeyId = '8117b9a4-{redacted part}';
const merchantSecretKey = 'EeEwkwwKSBGyWJE{redacted part}';

The method that gets called when the user fills in the form data, but hardcoding the payload for now...

var curDate = new Date().toGMTString();

var payload = {
    "type": "enrollable card",
    "card": {
        "number": "4111111111111111",
        "expirationMonth": "09",
        "expirationYear": "2022",
        "securityCode": "123"
    },
    "billTo": {
        "address1": "8310 Capital of Texas Highway North",
        "address2": "Bluffstone Drive",
        "locality": "Austin",
        "administrativeArea": "TX",
        "postalCode": "78731",
        "country": "US"
    }
};

var apiUrl = 'https://' + requestHost + '/tms/v1/instrumentidentifiers';
var targetUrl = '/tms/v1/instrumentidentifiers';

var method = 'post';
var sha256digest = CryptoJS.SHA256(payload);
var base64sha256 = CryptoJS.enc.Base64.stringify(sha256digest);
var computedDigest = 'SHA-256=' + base64sha256;

var postHeaderHash = {
    host: requestHost,
    date: curDate,
    '(request-target)': method + ' ' + targetUrl,
    digest: computedDigest,
    "v-c-merchant-id": merchantId
};

var postConfig = {
    algorithm: 'HmacSHA256',
    keyid: merchantKeyId,
    secretkey: merchantSecretKey,
    headers: ['host', 'date', '(request-target)', 'digest', 'v-c-merchant-id']
}

var config = postConfig;
var headerHash = postHeaderHash;

var sig = this.computeHttpSignature(config, headerHash);

const options = {
    headers: {
        "v-c-merchant-id": merchantId,
        "v-c-date": curDate,
        "Digest": computedDigest,
        "Signature": sig,
        "Content-Type": 'application/json'
    }
};

const csResponse = axios.post(apiUrl, payload, options);

And of course the method that generates the signature...

// Cybersource Helper function 
computeHttpSignature(config, headerHash) {
var template = 'keyid="${keyid}", algorithm="${algorithm}", headers="${headers}", signature="${signature}"',
    sig = template;

// compute sig here
var signingBase = '';
config.headers.forEach(function (h) {
    if (signingBase !== '') { signingBase += '\n'; }
    signingBase += h.toLowerCase() + ": " + headerHash[h];
});

var hashf = (function () {
    switch (config.algorithm) {
        case 'SHA256withRSA': return CryptoJS.HmacSHA256;
        default: return CryptoJS.HmacSHA256;
    }
}());


var words = CryptoJS.enc.Base64.parse(config.secretkey);
// eslint-disable-next-line no-unused-vars
var reword = CryptoJS.enc.Base64.stringify(words)

var hash = hashf(signingBase, words);
var signatureOptions = {
    keyid: config.keyid,
    algorithm: config.algorithm,
    headers: config.headers,
    signature: CryptoJS.enc.Base64.stringify(hash)
};

// build sig string here
Object.keys(signatureOptions).forEach(function (key) {
    var pattern = "${" + key + "}",
        value = (typeof signatureOptions[key] != 'string') ? signatureOptions[key].join(' ') : signatureOptions[key];
    sig = sig.replace(pattern, value);
});

return sig;
}

 Please help, pulling my hair out on this one!

travist6983
Member
3 REPLIES 3

I am also confused and in need of light on this same issue. Need help.

 

Virginia587
Member

Since the header hash is used for generating the signature, and date is part of it, did you verify if the date is in the expected format ? May be compare every parameter used for hashing to what is working from Postman v/s the code ?

rajvpate
Administrator Administrator
Administrator

Hi, 

I have been encountering an "Authentication Failed" error when making POST requests to the Cybersource API from Apigee X. i have verified that all headers including the date header are correctly set and following the same process that works in Postman, I'm still facing this issue.

Could anyone who has dealt with similar authentication problems share any insights or clues you might have found?