VMware vSphere Web Services SDK编程指南(五)- 5.4 客户端应用(Web 服务器会话令牌)

5.4 Web 服务器会话令牌


本章包括以下主题:

■ 5.1 vCenter 服务器连接
■ 5.2 与 vCenter 服务器建立一个单点登录会话
■ 5.3 使用用户名和密码凭证建立一个会话
5.4 Web 服务器会话令牌
■ 5.5 vSphere API 的多个版本
■ 5.6 标识由服务器支持的API版本
■ 5.7 Sample 应用程序

接前篇从第4节开始


与其他Web服务一样,vSphere Web 服务通过在 HTTP 头中使用一个令牌来标识会话为每个客户端连接维护会话状态。vSphere 服务器对客户端连接请求响应中返回一个会话令牌给客户端,客户端和服务器之间的后续消息会自动包含该令牌。

在 SDK\vsphere-ws\java\JAX-WS\samples\com\vmware\ 目录中的每个独立案例都使用 JAX-WS TrustAllTrustCertificates 类(本节的 VMPromoteDisks.java 代码片段中)来忽略证书,获取一个会话令牌,然后连接到服务器。


注意:我们不建议你在生产环境中信任所有证书。相反,你可以查看示例代码使用的 JAX-WS 库如何创建连接,但设置了 SSL 策略后只有通过信任的证书才允许连接。


获取和存放 cookie 到消息头的逻辑如下:

//cookie logic
List cookies = (List) headers.get("Set-cookie");
cookieValue = (String) cookies.get(0);
StringTokenizer tokenizer = new StringTokenizer(cookieValue, ";");
cookieValue = tokenizer.nextToken();
String path = "$" + tokenizer.nextToken();
String cookie = "$Version=\"1\"; " + cookieValue + "; " + path;

// set the cookie in the new request header
Map map = new HashMap();
map.put("Cookie", Collections.singletonList(cookie));

((BindingProvider) vimPort).getRequestContext().put(
MessageContext.HTTP_REQUEST_HEADERS, map);

使用 JAX-WS 访问 HTTP 端点
使用 JAX-WS 绑定访问任何 HTTP 端点的步骤列出于 VMPromoteDisks.java 代码片段(本节后面)的起始位置,这些步骤包括 vSphere Web Services SDK 服务器 URL、vSphere 服务器对象和变量。

1 在这个示例中我们使用 TrustManager 类接受所有证书(非生产环境,生产环境需实现证书支持)。

private static class TrustAllTrustManager implements
        javax.net.ssl.TrustManager, javax.net.ssl.X509TrustManager {

    public java.security.cert.X509Certificate[] getAcceptedIssuers() {
        return null;
    }

    public boolean isServerTrusted(java.security.cert.X509Certificate[] certs) {
        return true;
    }

    public boolean isClientTrusted(java.security.cert.X509Certificate[] certs) {
        return true;
    }

    public void checkServerTrusted(java.security.cert.X509Certificate[] certs,
            String authType) throws java.security.cert.CertificateException {
        return;
    }

    public void checkClientTrusted(java.security.cert.X509Certificate[] certs,
            String authType) throws java.security.cert.CertificateException {
        return;
    }
}

2 在 main 方法中包含服务器 URL 和 凭证作为参数。

public static void main(String[] args) {
    try {
        String serverName = args[0];
        String userName = args[1];
        String password = args[2];
        String url = "https://"+serverName+"/sdk/vimService";

3 为访问 vSphere 服务器对象声明以下类型的变量:
■ ManagedObjectReference:用于 ServiceInstance.
■ VimService 对象: 用于访问 Web service.
■ VimPortType 对象: 用于访问 vSphere API 中定义的所有方法.
■ ServiceContent : 用于访问服务器上的托管对象服务.

变量声明如下:

ManagedObjectReference SVC_INST_REF
VimService vimService;
VimPortType vimPort;
ServiceContent serviceContent;

4 声明一个主机名验证器,它将自动启用连接,主机名验证器在 SSL 握手过程中被调用。

HostnameVerifier hv = new HostnameVerifier() {
    public boolean verify(String urlHostName, SSLSession session) {
        return true;
    }
};

5 实例化信任管理器对象

// Create the trust manager.
javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
javax.net.ssl.TrustManager tm = new TrustAllTrustManager();
trustAllCerts[0] = tm;

6 创建 SSL 上下文

javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");

7 创建会话上下文

javax.net.ssl.SSLSessionContext sslsc = sc.getServerSessionContext();

8 初始化上下文;会话上下文获得信任管理器。

sslsc.setSessionTimeout(0);
sc.init(null, trustAllCerts, null);

9 使用默认 socket 工厂为安全连接创建 socket

javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

10 设置默认主机名验证器启动连接

HttpsURLConnection.setDefaultHostnameVerifier(hv);

访问 vSphere Server
使用 vSphere Web Services API 创建连接的步骤如下:

1 创建一个用于服务器上的 ServiceInstance 对象的托管对象引用。

ManagedObjectReference SVC_INST_REF = new ManagedObjectReference();
SVC_INST_REF.setType("ServiceInstance");
SVC_INST_REF.setValue("ServiceInstance");

2 创建 VimService 对象用于获取 VimPort 绑定提供者,BindingProvider 对象提供到请求/响应中协议字段的访问,获得请求上下文可用于处理消息请求。

VimServiceLocator 和 VimPortType 对象提供到 vSphere 服务器的访问。getVimPort 方法返回一个可提供访问 vSphere API 方法的 VimPortType 对象。

vimService = new VimService();
vimPort = vimService.getVimPort();
Map<String, Object> ctxt = ((BindingProvider) vimPort).getRequestContext();

3 在请求上下文中存储服务器URL,并指定 true 来维护客户机和服务器之间的连接,客户端 API 在其请求中将包含服务器的 HTTP cookie 以维护会话; 如果上下文不设置 true ,服务器会对每个请求开启一个新的会话。

ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
ctxt.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, **true**);

4 获取 ServiceInstance 内容(即 ServiceContent 数据对象)并登录服务器。

serviceContent = vimPort.retrieveServiceContent(SVC_INST_REF);
vimPort.login(serviceContent.getSessionManager(),
              userName, password, null);
isConnected = true;

关闭连接
使用 VimPort 对象关闭连接,始终关闭服务器连接以维护安全性。

...
                vimPort.logout(serviceContent.getSessionManager());
        } catch (Exception e) {
            System.out.println(" Connect Failed ");
            e.printStackTrace();
        }
    }//end main()
}// end class TestClient

使用 Java 示例作为参考
下面的代码片段取自 SDK\vsphere-ws\java\JAX-WS\samples\com\vmware\vm\
VMPromoteDisks.java 示例显示了服务器连接的另外一种实现。

Example: 获取一个会话令牌 - VMPromoteDisks.java 代码片段

...
private static String cookieValue = "";
private static Map headers = new HashMap();
...
private static void trustAllHttpsCertificates()
throws Exception {

    javax.net.ssl.TrustManager[] trustAllCerts = new javax.net.ssl.TrustManager[1];
    javax.net.ssl.TrustManager tm = new TrustAllTrustManager();
    trustAllCerts[0] = tm;
    javax.net.ssl.SSLContext sc = javax.net.ssl.SSLContext.getInstance("SSL");
    javax.net.ssl.SSLSessionContext sslsc = sc.getServerSessionContext();
    sslsc.setSessionTimeout(0);
    sc.init(null, trustAllCerts, null);
    javax.net.ssl.HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
}
...
private static void connect()
throws Exception {
    HostnameVerifier hv = new HostnameVerifier() {
        public boolean verify(String urlHostName, SSLSession session) {
            return true;
        }
};

trustAllHttpsCertificates();
HttpsURLConnection.setDefaultHostnameVerifier(hv);

SVC_INST_REF.setType(SVC_INST_NAME);
SVC_INST_REF.setValue(SVC_INST_NAME);

vimService = new VimService();
vimPort = vimService.getVimPort();
Map ctxt = ((BindingProvider)vimPort).getRequestContext();

ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
ctxt.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);

serviceContent = vimPort.retrieveServiceContent(SVC_INST_REF);
headers = (Map((BindingProvider)vimPort).getResponseContext().
get(MessageContext.HTTP_RESPONSE_HEADERS);

vimPort.login(serviceContent.getSessionManager(),userName,password, null);
isConnected = true;

propCollectorRef = serviceContent.getPropertyCollector();
rootRef = serviceContent.getRootFolder();
}
...




原文:
VMware vSphere 6.5 Documentation Center:Client Applications

你可能感兴趣的:(vSphere,Web,Services,SDK编程指南,vmware,vSphere,web,services,sdk)