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");