本章包括以下主题:
■ 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