我不是REST API的专家,在尝试调用Duo 2 factor身份验证API时遇到了问题:https://www.duosecurity.com/docs/authapi#api-details
它看起来非常直接,但我认为我遗漏了一些东西,我已经为此工作了2天没有成功。
我正在使用Jersey,它给了我以下错误:
java.lang.IllegalArgumentException: Illegal character(s) in message header value: Basic RElGUE1MSVQyMU40OUhORURL[...]YTYzOQ==
(我已缩短上面一行中的键)
API使用HTTP基本身份验证来验证请求。
我确实按照文档中的说明进行了身份验证。我确实生成了HTTP密码作为请求的HMAC签名。我也按照文档中的说明构建了签名,首先从我的请求构建一个ASCII字符串,然后将这些组件与换行符连接起来并计算规范表示的HMAC-SHA1,然后在Base64中编码用户名:hmac。 / p>
我想我可能会误解编码部分的某些内容或者没有正确地做某事。
以下是我的代码的一部分:
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;
}
答案 0 :(得分:1)
确保您的requestXML或任何标头值没有任何非法字符,并将其替换为......
aXmlRequest=aXmlRequest.replaceAll("\n", "");
答案 1 :(得分:0)
我想这是我目前面临的同样问题。
非法字符是auth标头末尾的换行符。
请查看Java: fetch URL with HTTPBasic Authentication了解详情。
我使用commons-codec库中的org.apache.commons.codec.binary.Base64类来获取Base64加密。我不确定,但也许它可以解决你的问题。
祝你好运, 菲利克斯