08-30-2018 10:53 AM
Hi Team,
I reffed to https://duo.com/docs/authapi#endpoints to use DUO Auth API for check and preauth.
i used this https://github.com/duosecurity/duo_client_java/blob/master/duo-client/src/main/java/com/duosecurity/client/Http.java and with this the ping and check API’ are success but Preauth api i am getting 40103 Invalid signature in request credentials and i am using the correct ikey and skey that are created for Auth API in duo admin console
Could you please suggest me on how to resolve this issue.
Thank you
08-31-2018 12:35 PM
Per this Duo KB article, please try the following suggestions:
Verify that the signature is encoded in hexadecimal ASCII; is using the correct HMAC-SHA1 signature as the password; lists parameters in alphabetical order.
11-13-2018 10:31 AM
@DuoKristina what exactly does that mean? I’m using Postman simply to test and I’m receiving the same error.
11-13-2018 11:41 AM
Hey @humblecoder,
Did you take a look at the KB article I referenced, which lists common Duo error codes and possible causes?
11-13-2018 12:05 PM
@DuoKristina I did indeed. In fact I’d seen it before coming here. I don’t mean to be obtuse, but are you referring to the parameter structure as a “signature”? I’ve never seen “signature” in that context and have no idea how it’s being used.
Also, while the KB article ostensibly says what the fix is, it doesn’t make clear how that is accomplished. I mean, from my perspective, I’m sending the request in plain text via PostMan. I can’t imagine what else to fix.
Regards
11-13-2018 12:37 PM
By “signature” we do refer to the computed SHA1 of the API request (with parameters) as described in here: Auth API | Duo Security.
Are you also having a success on /check
but fail on /preauth
? Or, is nothing successful?
11-13-2018 03:10 PM
@DuoKristina Actually, I can’t get anything to succeed. Here is the JS I’m using to create the relevant params in PostMan:
let curDate = (new Date()).toUTCString()
let myHost = 'HIDDEN-HOST'
let params = {
'device': 'auto',
'factor': 'push',
'username': 'HIDDEN-NAME'
}
let urlEncodedParams = []
_.forOwn(params,(v,k)=>{
urlEncodedParams.push(encodeURIComponent(k) + '=' + encodeURIComponent(v))
})
let sigComponents = {
'date': curDate,
'host': myHost,
'method': 'POST',
'path': '/auth/v2/auth',
'urlParam': urlEncodedParams.join('&')
}
let ■■■■ing = Object.values(sigComponents).join('\r\n')
let hmacSignature = CryptoJS.HmacSHA1(sigComponentValueString, 'HIDDEN-STRING').toString()
pm.environment.set("env_new_date", curDate)
pm.environment.set("env_hmac_signature", hmacSignature);
console.log(sigComponentValueString)
Obviously a convoluted process (especially given the nature of the requirement), but is there anything glaringly wrong.
11-15-2018 07:16 AM
@DuoKristina It would be nice to have far more descriptive errors, especially in “development”. Perhaps we could see on our dashboard what was sent vs what the server compared it to.
05-06-2019 03:21 PM
I am also having the same issue on POSTMAN. I put my skey(Password) and ikey(Username) under Authorization, after selecting Basic Auth.
POSTMAN created the Authorization Header. I am passing “Date” and “Content-Type” in the header".
I am getting {“code”: 40103, “message”: “Invalid signature in request credentials”, “stat”: “FAIL”}
05-06-2019 03:22 PM
@DuoKristina - I did try to use the python code at Auth API | Duo Security to generate “Authorization header” but code is throwing
NameError: name ‘unicode’ is not defined
05-19-2019 12:14 PM
I was running into the same problem. I figured out the solution to it with postman. When DUO api is referring to sending the signature you need to dynamically build the signature using the pre-request script feature in postman. In the API documentation they talk about constructing the signature, this is what they are referring to. In postman the pre-request script will set the signature as a postman environment variable which you will access in the header section. Below is the script I used in the pre-request script to build using their example in the api section and it gave me the correct signature.
You can verify the information by opening up the postman console. In your postman headers you will need to add Date with value of {{timestampHeader}} and Authorization with value of {{hmacAuthHeader}}
The Body tab you will want to select x-www-form-urlencoded. My recommendation would be to start out small and use api: /auth/v2/preauth for your own example. Use the username and alias for value. Make sure that the pre-request script body value matches the same alias value you use in the body section. The script below will fail using their information from the api page. When you replace everything with your own information it should work. This is how I got mine to work. The added console lines will show up in postman console where you can verify the different steps of information. Please be aware the hostname below will need to be replaced because the forum removed the information for client key and secret key. Go to the Auth API | Duo Security page and search for construct the signature and use the host listed, the ikey(CLIENT_KEY) and the secret key they have listed in their test test. One last thing I was never able to use the full username email instead I added a new alias with a short name to the user and made sure that what I was requesting on for username. If I used the full email it was never able to work. example: bob@bob.com I added alias bob and did username=bob . Hopefully this will help others understand what is needed. Good luck
function getAuthHeader(httpMethod, requestUrl, requestBody) {
console.log(requestBody); //body data
console.log(httpMethod); // http type: POST, GET, ETC
var CLIENT_KEY = 'nnnn';
var SECRET_KEY = 'nnnn';
var AUTH_TYPE = 'HMAC-SHA1';
var moment = require('moment')
/* Uncomment out lines below to use your test for getting correct formatted time and date */
/* var timestamp = moment().format("ddd, DD MMM YYYY HH:mm:ss ZZ");
pm.environment.set("timestampHeader",timestamp);*/
var timestamp = "Tue, 21 Aug 2012 17:29:18 -0000"; /* Only for example */
pm.environment.set("timestampHeader",timestamp);
var hostname = "nnnn-xxxxxxxx.duosecurity.com";
var apicall = "/accounts/v1/account/list"
var body = "realname=First%20Last&username=root"
var requestData = timestamp+"\n"+"POST"+"\n"+hostname+"\n"+apicall+"\n"+body;
console.log(requestData);
var hmacDigest = CryptoJS.HmacSHA1(requestData, SECRET_KEY);
console.log(hmacDigest);
var prebase = CLIENT_KEY+":"+hmacDigest;
console.log(prebase);
var baseComplete = btoa(prebase);
console.log(baseComplete);
var authHeader = "Basic "+baseComplete;
return authHeader;
}
postman.setEnvironmentVariable(‘hmacAuthHeader’, getAuthHeader(request[‘method’], request[‘url’], request[‘data’]));
09-12-2019 10:35 AM
I used the above Pre Request Script, defined the environment variables. Still getting 40101.
09-13-2019 05:53 AM
Thank you xrave, finally worked. The problem was that I was selecting “Basic Auth” under Authorization. It should be “No Auth” selected. I used script from above, using method as GET.
09-16-2020 09:19 AM
hi ,
i have given below script in pre request script and getting an SyntaxError: Invalid or unexpected token,please help where i am doing wrong
function getAuthHeader(httpMethod, requestUrl, requestBody) {
console.log(requestBody);
console.log(httpMethod); // http type: POST, GET, ETC*/
var CLIENT_KEY = ‘xxxx’;
var SECRET_KEY = ‘xxxxx’;
var AUTH_TYPE = ‘HMAC-SHA1’;
var moment = require(‘moment’)
/*Uncomment out lines below to use your test for getting correct formatted time and date */
var timestamp = moment().format(“ddd, DD MMM YYYY HH:mm:ss ZZ”);
pm.environment.set(“timestampHeader”,timestamp);
/var timestamp = “Tue, 21 Aug 2012 17:29:18 -0000”; / Only for example */
/pm.environment.set(“timestampHeader”,timestamp);/
var hostname = “api-xxxxxxxx
var apicall = “/admin/v1/users”
var body = "realname=testingggggg&username=root"
var requestData = timestamp+"\n"+“POST”+"\n"+hostname+"\n"+apicall+"\n"+body;
console.log(requestData);
var hmacDigest = CryptoJS.HmacSHA1(requestData, SECRET_KEY);
console.log(hmacDigest);
var prebase = CLIENT_KEY+":"+hmacDigest;
console.log(prebase);
var baseComplete = btoa(prebase);
console.log(baseComplete);
var authHeader = "Basic "+baseComplete;
return authHeader;
}
postman.setEnvironmentVariable(‘hmacAuthHeader’, getAuthHeader(request[‘method’], request[‘url’], request[‘data’]));
10-08-2020 04:34 PM
I ran into the same issue when copying/using the pre-script. Be sure to replace the single quotes for the section below. When copied, they came across as unrecognized in Postman.
postman.setEnvironmentVariable(‘hmacAuthHeader’, getAuthHeader(request[‘method’], request[‘url’], request[‘data’]));
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide