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

xiaoxiao2021-02-28  81

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<String, Object> 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

转载请注明原文地址: https://www.6miu.com/read-42957.html

最新回复(0)