API调用授权认证
上次更新时间: 2020/09/25
通过HTTP或HTTPS的GET方式进行CaaS / CVPC API的调用时,需在HTTP Query String中传入认证相关参数,当CaaS / CVPC API服务平台接收到此调用时,会进一步验证该调用是否带有合法的验证码(signature)。客户需事先在CloudBOSS 云端服务系统入口网站上取得一组合法的CaaS / CVPC API Key,包含Access Key及Secret Key,以便运算出验证码。
以下为一CaaS / CVPC API调用的实际示例:
https://hws.hicloud.hinet.net/cloud_hws/api/hws/?action=runInstances&version=2013-03-29
&chtAuthType=hwspass&imageId=hi-olajtpss&instanceType=HC1.S.LINUX&monitoringEnabled=false
&instanceName=haha&count=1&accessKey=U0U0MU5UQXhNREF3TVRFek5qSTVPRFkxTURneU1UWT0
&expires=2013-03-29T17:50:04Z&signature=VBUfKTt48Wf6xbdny98N4Gi07f4
拆解上列调用实例,说明如下。
- 服务平台网址(basic url):
https://hws.hicloud.hinet.net/cloud_hws/api/hws/?
- 指令内容(command string):
action=runInstances&version=2013-03-29&chtAuthType=hwspass&imageId=hi-olajtpss&instanceType=HC1.S.LINUX&monitoringEnabled=false&instanceName=haha&count=1&accessKey=U0U0MU5UQXhNREF3TVRFek5qSTVPRFkxTURneU1UWT0&expires=2013-03-29T17:50:04Z
- 验证码(signature):
signature=VBUfKTt48Wf6xbdny98N4Gi07f4
每个CaaS / CVPC API调用,均以服务平台网址(basic url)、指令内容(command string)、验证码(signature)的内容串接起来,才可视为一有效的CaaS / CVPC API调用。
验证码产生的方式如下:
- 以UTF-8格式将指令内容(command string)进行编码。
- 将CaaS / CVPC API调用中的指令内容(command string)以”&”符号分隔,可得到多组键值/参数对应。
- 按照键值进行参数排序,重新组合指令内容。(这边采用自然排序法,即是以字符符号进行排序),排序结果如下:
- 将指令内容中的大写均转换为小写,如下:
- 搭配Secret Key并使用HMAC SHA-1加密算法将指令内容进行加密,进一步通过Base64编码方式将加密结果进行编码,而编码结果中可能包含URL之三个特殊字符("+", "/", "="),取代此三个特殊字符后即为验证码(signature),取代原则如下表1.,验证码格式如下: signature=VBUfKTt48Wf6xbdny98N4Gi07f4。
- 将验证码串在服务平台网址及指令内容后面,即是有验证功能的CaaS / CVPC API 调用。
action=runInstances
version=2013-03-29
imageId=hi-olajtpss
instanceType=HC1.S.LINUX
monitoringEnabled=false
instanceName=haha
count=1
accessKey=U0U0MU5UQXhNREF3TVRFek5qSTVPRFkxTURneU1UWT0
expires=2013-03-29T17:50:04Z
accessKey=U0U0MU5UQXhNREF3TVRFek5qSTVPRFkxTURneU1UWT0&action=runInstances
&chtAuthType=hwspass&count=1&expires=2013-03-29T17:50:04Z&imageId=hi-olajtpss&instanceName=haha&instanceType=HC1.S.LINUX&monitoringEnabled=false&version
=2013-03-29
accesskey=u0u0mu5uqxhnref3tvrfek5qstvprfkxturneu1uwt0&action=runinstances
&chtauthtype=hwspass&count=1&expires=2013-03-29T17:50:04Z&imageid=hi-olajtpss&instancename=haha&instancetype=hc1.s.linux&monitoringenabled=false&version=2013-03-29
表1.
原特殊字符 |
取代字符 |
|---|---|
| "+" | "*" |
| "/" | "-" |
| "=" | ""(空字符) |
https://hws.hicloud.hinet.net/cloud_hws/api/hws/?action=runInstances &version=2013-03-29&chtAuthType=hwspass &imageId=hi-olajtpss&instanceType=HC1.S.LINUX&monitoringEnabled=false&instanceName=haha &count=1&accessKey=U0U0MU5UQXhNREF3TVRFek5qSTVPRFkxTURneU1UWT0&expires=2013-03-29T17:50:04Z &signature=VBUfKTt48Wf6xbdny98N4Gi07f4
使用hws-signature Java函式取得验证码
- • 以下是通过JAVA程序产生验证码示例程序:
package chttl.cloud.hws;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class HWSSignature {
/**
* Generate signature from your secret key and URL format string.
* And use the Overload mechanism to call "generateSignature(String userSecretKey,
String commandString)" method for the return value
* @param String userSecretKey
* @param String unsignedUrl
* @return String URL
*/
public static String getSignedUrl(String userSecretKey, String unsignedUrl){
String commandString =unsignedUrl.substring(unsignedUrl.indexOf('?') + 1);
return unsignedUrl + "&signature=" + generateSignature(userSecretKey, commandString);
}
/**
* Generate signature string from your secret key string and the command string.
* And use the Overload mechanism to call "generateSignature(String userSecretKey,
Map<String, List<String>> arguments)" method for the return value.
* @param String userSecretKey
* @param String commandString
* @return String signature
*/
public static String generateSignature(String userSecretKey, String commandString) {
Map<String, List<String>> arguments = new HashMap<String, List<String>>();
String decodedUrl = "";
try {
decodedUrl = URLDecoder.decode(commandString, "utf8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String [] commands = decodedUrl.split("&");
for(String command : commands) {
String [] keyValues = command.split("=");
if(arguments.containsKey(keyValues[0])){
List<String> valueList=arguments.get(keyValues[0]);
valueList.add(keyValues[1]);
}else{
List<String> valueList = new ArrayList<String>();
valueList.add(keyValues[1]);
arguments.put(keyValues[0], valueList);
}
}
return generateSignature(userSecretKey, arguments);
}
/**
* Generate signature string from your secret key string and Map object which is composed of
command pairs.
* But the "arguments" hash map should not contain "signature" key entry.
* @param String userSecretKey
* @param Map<String, List<String>> arguments
* @return String mySignature
*/
public static String generateSignature(String userSecretKey, Map<String, List<String>> arguments){
List<String> argumentNameList = new ArrayList<String>();
String mySignature = null;
for(String name : arguments.keySet()) {
argumentNameList.add(name);
}
Collections.sort(argumentNameList);
String requestMsg = null;
for(String argumentName : argumentNameList){
List<String> valueList = arguments.get(argumentName);
for(int listCount=0 ; listCount<valueList.size() ; listCount++){
if(requestMsg == null){
requestMsg = argumentName + "=" + valueList.get(listCount);
}else {
requestMsg += "&" + argumentName + "=" + valueList.get(listCount);
}
}
}
requestMsg = requestMsg.toLowerCase();
System.out.println(requestMsg);
try {
Mac mac;
mac = Mac.getInstance("HmacSHA1");
SecretKeySpec keySpec = new SecretKeySpec(userSecretKey.getBytes(), "HmacSHA1");
mac.init(keySpec);
mac.update(requestMsg.getBytes());
byte[] encryptedBytes = mac.doFinal();
mySignature = getBase64String(encryptedBytes);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
}
return mySignature;
}
/**
* Generate Base64 encoded string from the byte buffer.
* Handle and prevent URL from containing the special characters
* @param byte[] encryptedBytes
* @return String encodeString
*/
private static String getBase64String(byte[] encryptedBytes) {
String encodeString = null;
encodeString = new String(Base64.encodeBase64(encryptedBytes));
encodeString = encodeString.replace("+", "*");
encodeString = encodeString.replace("/", "-");
encodeString = encodeString.replace("=", "");
return encodeString;
}
}
- 调用说明:
HWSSignature.getSignedUrl(" your secretKey "," https://CaaS / CVPC API basic url/?command string "));
调用实例:
HWSSignature.getSignedUrl("WWpJNU16a3pOV1JsWWpNeU5HVXdOMkkxTURNd1lUbG1OMlEwTXp
SaFptST0","https://hws.hicloud.hinet.net/cloud_hws/api/hws/?action=runInstances&version=2013-03-29&chtAuthType=hwspass&imageId=hi-olajtpss&instanceType=HC1.S.LINUX&monitoringEnabled=false&instanceName=haha&count=1
&accessKey=U0U0MU5UQXhNREF3TVRFek5qSTVPRFkxTURneU1UWT0&expires=2013-03-29T17:50:04Z");
输出:
https://hws.hicloud.hinet.net/cloud_hws/api/hws/?action=runInstances&version=2013-03-29&chtAuthType=hwspass&imageId=hi-olajtpss&instanceType=HC1.S.LINUX&monitoringEnabled=false&instanceName=haha&count=1
&accessKey=U0U0MU5UQXhNREF3TVRFek5qSTVPRFkxTURneU1UWT0&expires=2013-03-29T17:50:04Z&signature=VBUfKTt48Wf6xbdny98N4Gi07f4
也可以通过 HWSSignature.generateSignature(" your secretKey ","command string "),取得验证码
调用实例: HWSSignature.generateSignature("WWpJNU16a3pOV1JsWWpNeU5HVXdOMkkxTURNd1lUbG1OMlEwTX
pSaFptST0", "action=runInstances&version=2013-03-29&chtAuthType=hwspass&imageId=hi-olajtpss&instanceType=HC1.S.LINUX&monitoringEnabled=false&instanceName=haha&count=1
&accessKey=U0U0MU5UQXhNREF3TVRFek5qSTVPRFkxTURneU1UWT0&expires=2013-03-29T17:50:04Z")
输出:
VBUfKTt48Wf6xbdny98N4Gi07f4
Note. 本案例程序使用Apache common code进行Base64编码,使用时需import该函式库。