Reputation: 4048
I am not an expert with REST APIs and I am running into issues when trying to makes calls to the Duo 2 factor authentication API: https://www.duosecurity.com/docs/authapi#api-details
It looks really straight forward, but I think I am missing something, I have been working on this for 2 days without success.
I am using Jersey, which gives me the following error:
java.lang.IllegalArgumentException: Illegal character(s) in message header value: Basic RElGUE1MSVQyMU40OUhORURL[...]YTYzOQ==
(I have shortened the key in the above line)
The API uses HTTP Basic Authentication to authenticate requests.
I did follow the instructions in the doc for the authentication. I did generate the HTTP Password as an HMAC signature of the request. I also did build the signature as explained in the doc, by first building an ASCII string from my request, then by concatenating the components with line feeds and computing the HMAC-SHA1 of the canonical representation, then encoding username:hmac in Base64.
I think I might be misunderstanding something on the encoding part or not doing something properly.
Here is part of my code:
public Enroll enroll(String username){
HashMap<String, String> formData = new HashMap<String, String>();
formData.put("username", username);
String date = generateDate();
String signature = constructSignature("POST", "/auth/v2/enroll", formData);
String authValue = generateAuthValue(secretKey, signature);
Enroll response = service.path("auth").path("v2").path("enroll").header("Date", date)
.header("Content-Type", "application/x-www-form-urlencoded")
.header("Authorization", authValue).type(MediaType.APPLICATION_FORM_URLENCODED_TYPE)
.accept(MediaType.APPLICATION_JSON_TYPE).post(Enroll.class, formData);
return response;
}
public String generateAuthValue(String secretKey, String signature){
String hmacValue = calcShaHash(signature, integrationKey, secretKey);
return hmacValue;
}
private String constructSignature(String method, String path, HashMap<String, String> params){
String date = generateDate();
String lineFeed = "\n";
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(date);
stringBuilder.append(lineFeed);
stringBuilder.append(method);
stringBuilder.append(lineFeed);
stringBuilder.append(apiHostName);
stringBuilder.append(lineFeed);
stringBuilder.append(path);
stringBuilder.append(lineFeed);
stringBuilder = urlEncodeParameters(params, stringBuilder);
return stringBuilder.toString();
}
private StringBuilder urlEncodeParameters(HashMap<String, String> params, StringBuilder stringBuilder){
try{
for (Map.Entry<String, String> entry : params.entrySet()){
stringBuilder.append(URLEncoder.encode(entry.getKey().toString(), "UTF-8"));
stringBuilder.append("=");
stringBuilder.append(URLEncoder.encode(entry.getValue().toString(), "UTF-8"));
stringBuilder.append("\n");
//signature.concat(encoded);
}
}catch (UnsupportedEncodingException e){
e.printStackTrace();
}
return stringBuilder;
}
public static String calcShaHash(String data, String integrationKey, String secretKey){
String HMAC_SHA1_ALGORITHM = "HmacSHA1";
StringBuilder result = new StringBuilder();
try{
Key signingKey = new SecretKeySpec(secretKey.getBytes("UTF-8"), HMAC_SHA1_ALGORITHM);
Mac mac = Mac.getInstance(HMAC_SHA1_ALGORITHM);
mac.init(signingKey);
byte[] rawHmac = mac.doFinal(data.getBytes("UTF-8"));
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(integrationKey);
stringBuilder.append(":");
stringBuilder.append(Hex.encodeHexString(rawHmac).toString());
byte[] byteAuthorizationValue = stringBuilder.toString().getBytes("UTF-8");
result.append("Basic ");
result.append(Base64.encode(byteAuthorizationValue).toString());
}catch (Exception e){
e.printStackTrace();
}
return result.toString();
}
private String generateDate(){
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss ZZZZ");
String formattedDate = sdf.format(date);
return formattedDate;
}
Upvotes: 1
Views: 4600
Reputation: 1233
Make sure that your requestXML or any header value does not have any illegal characters and replace it like...
aXmlRequest=aXmlRequest.replaceAll("\n", "");
Upvotes: 1
Reputation: 135
I guess it is the same problem I am facing at the moment.
The illegal character is a new-line-character at the end of the auth header.
Take a look at Java: fetch URL with HTTPBasic Authentication for more information.
I use the org.apache.commons.codec.binary.Base64 class from the commons-codec library to get Base64 encryption. I'm not sure but maybe it solves your problem.
Best regards, Felix
Upvotes: 0