You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users-cn@cloudstack.apache.org by WXR <47...@qq.com> on 2013/06/22 06:00:38 UTC
请问cloudstack登录控制台处的链接里的token值是怎么计算出来的呢
查看控制台中,拼接的url(如 https://192-168-2-171.realhostip.com/ajax?token=45K5Eq2anYubuzbEKbUro1uDTOerLD-fyAnsSqu4Trm6bjw3d6iMRzwkUH7vwPn68nZ4mbKA0CcDKWeIoSXdZn8729dfhSoRO85_2SUEKPFwX8bzwilhNndxF976ZkE7NTYiWPweGKlK35yWzD_jni6Mm7rYOIm5VD2pabhr4tABSWWCWUMwXTfgSOM7Tg3FoaQehhPU7LGFs80CnbLK_kGFVEWpX1yWNrPTJbhi5kMz3AejhUqY6oYauk2gkYtoIqaUL9j1TpE#),token的值是如何计算来的?
源代码中:计算token的地方如下:
ConsoleProxyClientBase类:
ConsoleProxyPasswordBasedEncryptor encryptor = new ConsoleProxyPasswordBasedEncryptor(ConsoleProxy.getEncryptorPassword());
this.clientToken = encryptor.encryptObject(ConsoleProxyClientParam.class, clientParam);
ConsoleProxyPasswordBasedEncryptor类的带一个参数的构造器定义如下:
public ConsoleProxyPasswordBasedEncryptor(String password) {//注:这里的密码是一个可以构造KeyIVPair对象的json字符串,liangliang,meng
gson = new GsonBuilder().create();
keyIvPair = gson.fromJson(password, KeyIVPair.class);
}
中的String参数应该是一个json格式的字符串,用于初始化成员变量:keyIvPair.
构造器中的参数:ConsoleProxy.getEncryptorPassword(),代码如下:
static String encryptorPassword = genDefaultEncryptorPassword();
private static String genDefaultEncryptorPassword() {
try {
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
byte[] randomBytes = new byte[16];
random.nextBytes(randomBytes);
return Base64.encodeBase64String(randomBytes);
} catch (NoSuchAlgorithmException e) {
s_logger.error("Unexpected exception ", e);
assert(false);
}
return "Dummy";
}
该方法返回的是一个base64编码格式的字符串,根本不是json格式的字符串.根本无法用来初始化成员变量keyIvPair.不知道cloudstack是如何正常运行而且计算除了正确token值的?
换另外一种思路:为ConsoleProxyClientBase类添加一个新的构造器,如下:
public ConsoleProxyPasswordBasedEncryptor(KeyIVPair keyIvPair){
this.keyIvPair = keyIvPair;
}
先初始化一个KeyIVPair对象
SecureRandom random;
random = SecureRandom.getInstance("SHA1PRNG");
byte[] keyBytes = new byte[16];
random.nextBytes(keyBytes);
byte[] ivBytes = new byte[16];
random.nextBytes(ivBytes);
KeyIVPair keyIvPair = new KeyIVPair();
keyIvPair.setKeyBytes(keyBytes);
keyIvPair.setIvBytes(ivBytes);
构造一个ConsoleProxyPasswordBasedEncryptor对象.
ConsoleProxyPasswordBasedEncryptor encryptor3 = new ConsoleProxyPasswordBasedEncryptor(keyIvPair);
构造一个ConsoleProxyClientParam对象,ConsoleProxyClientParam cpcp = new ConsoleProxyClientParam();
cpcp.setAjaxSessionId("");//192.168.2.175|xK8unwqdz
cpcp.setClientHostAddress(ip);//*
cpcp.setClientHostPassword("xK8unwqdz");
//cpcp.setClientHostPort(8080);//*
//cpcp.setClientTag("cmdline"); //这个clientTag是什么,虚拟机的显示名称???
// cpcp.setClientTunnelSession(""); //ClientTunnelSession是什么,从何而来?
// cpcp.setClientTunnelUrl("clientTuneelUrl"); //ClientTunnelUrl,从何而来?
// cpcp.setTicket("ticket"); //不知道ticket是指什么?
//把cpcp对象转换为json字符串.
String json = gson.toJson(cpcp);
//计算token
String token = encryptor3.encryptText(json);
这样计算出来的token位数明显不对,应该是少了几个参数的值,问题是少加的几个参数从何而来的?源代码中是这样给出的:
private void doHandle(HttpExchange t) throws Exception, IllegalArgumentException {
String queries = t.getRequestURI().getQuery();
if(s_logger.isTraceEnabled())
s_logger.trace("Handle AJAX request: " + queries);
Map<String, String> queryMap = ConsoleProxyHttpHandlerHelper.getQueryMap(queries);
String host = queryMap.get("host");//liangliang
String portStr = queryMap.get("port");
String sid = queryMap.get("sid");
String tag = queryMap.get("tag");
String ticket = queryMap.get("ticket");
String ajaxSessionIdStr = queryMap.get("sess");
String eventStr = queryMap.get("event");
String console_url = queryMap.get("consoleurl");
String console_host_session = queryMap.get("sessionref");