Since I want to use it from Android, Base64.encodeBase64String (); is not used. Since I am studying, I will write the output code for confirmation as it is, and I hope that it will be useful for those who are studying like myself.
import java.net.URLEncoder;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.util.TreeMap;
import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Mac;
import android.util.Base64; //← Use this when using from Android
//import java.util.Base64;← Use this when using from normal Java
public static void main(String[] args) throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
String queryString = "";
String host = "http://<yourCloudStackHost>/client/api";
String apiUrl = "";
String apiKey = "yourApiKey";
Key secKey = new SecretKeySpec("yourSecretKey".getBytes(),"HmacSHA1");
TreeMap<String,String> params = new TreeMap<>();
params.put("response","json");
params.put("command","listZones");
params.put("apikey",apiKey);
for(String key:params.keySet()){
if(queryString.isEmpty()){
queryString = key + "=" + params.get(key);
}else{
queryString = queryString + "&" + key + "=" + params.get(key);
}
//System.out.println(key + "=" + params.get(key));
System.out.println(queryString);
}
String queryStringLow = queryString.toLowerCase();
System.out.println(queryStringLow);
//Hash with HMAC SHA1 using secret key
Mac mac = Mac.getInstance("HmacSHA1");
mac.init(secKey);
byte[] digest = mac.doFinal(queryStringLow.getBytes());
//BASE64 encoding
String b64 = Base64.getEncoder().encodeToString(digest);
//URL encoding
String signature = URLEncoder.encode(b64);
signature = signature.replaceAll("%0A",""); //Line feed code removal
//URL generation
apiUrl = host + "?" + queryString + "&signature=" + signature;
//For debugging
System.out.println(digest);
System.out.println(b64);
System.out.println(signature);
System.out.println(queryString + "&signature=" + signature);
System.out.println(apiUrl);
}
}
In apiURL,
http://<yourCloudStackHost>/client/api?apikey=<yourApiKey>&command=listZones&response=json&signature=<yourSignature>
It should come in, so copy this and try accessing it with a terminal etc.
curl -s 'http://<yourCloudStackHost>/client/api?apikey=<yourApiKey>&command=listZones&response=json&signature=<yourSignature>' | jq -C
Response result
{
"listzonesresponse": {
"count": 3,
"zone": [
{
"id": "e8ebfccb-eb38-43ed-8abf-XXXX",
"name": "weber",
"networktype": "Advanced",
"securitygroupsenabled": false,
"allocationstate": "Enabled",
"zonetoken": "42101a12-6299-32c7-a324-XXXX",
"dhcpprovider": "VirtualRouter",
"localstorageenabled": true,
"tags": []
},
{
"id": "95c8746d-57b3-421f-9375-XXXX",
"name": "lux",
"networktype": "Advanced",
"securitygroupsenabled": false,
"allocationstate": "Enabled",
"zonetoken": "de9e9a4f-696d-39f4-bb3e-XXXX",
"dhcpprovider": "VirtualRouter",
"localstorageenabled": true,
"tags": []
},
{
"id": "f4583787-7bff-461a-b026-XXXX",
"name": "farad",
"networktype": "Advanced",
"securitygroupsenabled": false,
"allocationstate": "Enabled",
"zonetoken": "a53d8e78-3c77-3352-8a04-XXXX",
"dhcpprovider": "VirtualRouter",
"localstorageenabled": true,
"tags": []
}
]
}
}
Response result when signature etc. is incorrect
{
"listzonesresponse": {
"errorcode": 401,
"errortext": "unable to verify user credentials and/or request signature"
}
}
Recommended Posts