I think you need to have valid login to access console of vm
We wanted the same access from our webclient for that we used login API
to first login and same session of httpclient to access console
I dont assure that its the perfect way but I thought it can help

Sent from my Windows Phone From: yao hu
Sent: ‎22-‎10-‎2013 08:55 AM
To: dev@cloudstack.apache.org; us...@cloudstack.apache.org
Subject: access instance's console using apikey failed
I compiled cloudstack 4.1.1 source code in cygwin, then test it using
jetty, it works fine. But, when I access instance's console through vnc
using apikey, it fails, the browser shows the follow message:
Access denied. Invalid web session or API key in request

my url:
http://localhost:8080/client/console?cmd=access&vm=b194369f-e0d4-45d8-a50f-09ec51095e68&apikey=fmS7oyThP6MGxN5X_CgeOCxQIqgTu5QFDz46r2Pv5kLp88EYYBquSu6_3s3d9MXdbUHPpxj5qDDy1jvhEpQWvQ&signature=y3dNHn580NJiCVRGwrBTR4JHImo%3D

I test the listAccounts api, it's ok.
my url:
http://localhost:8080/client/api?command=listAccounts&apikey=fmS7oyThP6MGxN5X_CgeOCxQIqgTu5QFDz46r2Pv5kLp88EYYBquSu6_3s3d9MXdbUHPpxj5qDDy1jvhEpQWvQ&signature=ALhJtw%2Bzi7Rcmo%2Bkk3xH3cTJgp4%3D

then, I debug the source code, find where it fails.
file: ConsoleProxyServlet.java
private boolean verifyRequest(Map<String, Object[]> requestParameters) {
try {
...
...

unsignedRequest = unsignedRequest.toLowerCase();

Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(),
"HmacSHA1");
mac.init(keySpec);
mac.update(unsignedRequest.getBytes());
byte[] encryptedBytes = mac.doFinal();
String computedSignature =
Base64.encodeBase64URLSafeString(encryptedBytes);
boolean equalSig = signature.equals(computedSignature);
if (!equalSig) {
s_logger.debug("User signature: " + signature + " is not equaled to
computed signature: " + computedSignature);
}
...
...
return equalSig;
} catch (Exception ex) {
s_logger.error("unable to verifty request signature", ex);
}
return false;
}

in this method, signature not equals to computedSignature, so it returns
false


then, I view ApiServer.java,the verifyRequest method:
public boolean verifyRequest(Map<String, Object[]> requestParameters, Long
userId) throws ServerApiException {
try {
...
...

unsignedRequest = unsignedRequest.toLowerCase();

Mac mac = Mac.getInstance("HmacSHA1");
SecretKeySpec keySpec = new SecretKeySpec(secretKey.getBytes(),
"HmacSHA1");
mac.init(keySpec);
mac.update(unsignedRequest.getBytes());
byte[] encryptedBytes = mac.doFinal();
String computedSignature = Base64.encodeBase64String(encryptedBytes);
boolean equalSig = signature.equals(computedSignature);
if (!equalSig) {
s_logger.debug("User signature: " + signature + " is not equaled to
computed signature: " + computedSignature);
}
...
...
return equalSig;
} catch (Exception ex) {
s_logger.error("unable to verifty request signature", ex);
}
return false;
}

these two verifyRequest method produce different signature, because the
former use :
String computedSignature =
Base64.encodeBase64URLSafeString(encryptedBytes);

while the later use:
String computedSignature = Base64.encodeBase64String(encryptedBytes);

this is why listAccouts works fine, but vnc console is failed.

when I replace Base64.encodeBase64URLSafeString by
Base64.encodeBase64String, vnc console is ok too.


so I am confused, why use different encode method? It is a bug?

Reply via email to