- Managing Global Settings with OptionManager
- Collecting Logs Using DiagnosticManager
- Sharing Sessions Among Different Applications
- Using Single Sign-On from the VI SDK to CIM
- Downloading and Uploading Files Using HTTP Access
- Multithreading with the VI SDK
- Versioning
- Following Best Practices for Performance and Scalability
- Considering Internationalization
- Summary
Sharing Sessions Among Different Applications
When a client first logs into VC or ESX server, a username and password are required to authenticate the user and grant access privileges. In the successive interactions with VC server, no username and password are needed. The HTTP session ID is instead used to track the user.
The HTTP session ID is essentially an HTTP cookie that is pushed from the server when the connection with the server is established. A UserSession is created after the login succeeds. There is mapping from the HTTP session to the user session on the server side so that the consecutive SOAP requests carrying an HTTP session ID automatically assume the privileges of a user. In other words, if your request has the same HTTP session ID as a current user, the system takes you as the user. There won't be a new UserSession for the new client.
In some of the cases, different clients need to share a user session. For example, in a VI Client plug-in, a Web application needs to use the session ID passed in from the VI Client in URL so that it can interact with the VC Server as if from the login user in the VI Client.
Now let's look at how to get the session ID and how to use it from another client.
Getting the Session ID
The code to get the session ID is as follows:
... VimPortType vimService = null; ManagedObjectReference mor = null; ServiceContent serviceContent = null; VimServiceLocator serviceLocator = new VimServiceLocator(); serviceLocator.setMaintainSession(true); try { vimService = serviceLocator.getVimPort(new URL(urlStr)); ManagedObjectReference serviceRef = new ManagedObjectReference(); serviceRef.setType("ServiceInstance"); serviceRef.set_value("ServiceInstance"); serviceContent = imService.retrieveServiceContent(serviceRef); if(serviceContent.getSessionManager()!=null) { vimService.login(serviceContent.getSessionManager(), username, password, null); } } catch (Exception e) { System.err.println("Exception: " + e.getMessage() ); } VimBindingStub vimStub = (VimBindingStub) vimService; org.apache.axis.client.Call call = vimStub._getCall(); org.apache.axis.MessageContext msgContext = call.getMessageContext(); String sessionString = (String) msgContext.getProperty( org.apache.axis.transport.http.HTTPConstants.HEADER_COOKIE); System.out.println(sessionString); ...
Notice that after logging in, the code converts the VimPortType to VimBindingStub and gets the Call, MessageContext objects. From the MessageContext, the session ID is extracted and printed.
In most cases, you only use the interface com.vmware.vim.VimPortType for operations in the VI SDK. This is, however, not enough to access the session information. The VimPortType interface provides a login service, but it does not expose session information.
To share a session, just grab the real implementation class, which is com.vmware.vim.VimBindingStub. With this implementation class, you can get and set session information, as shown in the previous samples.
public class com.vmware.vim.VimBindingStub extends org.apache.axis.client.Stub implements com.vmware.vim.VimPortType ()
The content of sessionString looks like this:
vmware_soap_session="B3240D15-34DF-4BB9-B902-A844FDF42E85"
This sample code is not always needed. In the case of the VI client plug-in, the VI client extracts the session ID and passes it in the URL to the Web application, which can use it to interact with the VC Server.
Using Session ID
Now, let's see how another client can use the session ID:
VimPortType vimService = null; ManagedObjectReference mor = null; ServiceContent serviceContent = null; VimServiceLocator serviceLocator = new VimServiceLocator(); serviceLocator.setMaintainSession(true); try { vimService = serviceLocator.getVimPort( new URL("https://localhost/sdk")); } catch (Exception e) { System.err.println("Exception: " + e.getMessage() ); } VimBindingStub vimStub = (VimBindingStub) vimService; vimStub._setProperty( org.apache.axis.transport.http.HTTPConstants.HEADER_COOKIE, "vmware_soap_session=\"B3240D15-34DF-4BB9-B902-A844FDF42E85\""); ...
This code's flow differs from the last code's flow because it doesn't require you to log in. The VimPortType is casted to VimBindingStub, and the session ID is set as the HTTP cookie.
Essentially, the session ID is a cookie string. It can be sent from one client to others in string format, in a local file, a URL, or messaging through the network. When setting the session, include "vmware_soap_session."
From the last line on, the consecutive code can send SOAP requests as if they were from the previous client, which prints the session ID.
Further Discussion
This introduction covers how to share the sessions in the code samples using Java. The previous samples actually assume using AXIS as the underlying Web Services engine. If you are using a different Web Services engine, find out how to retrieve the HTTP session and change the code accordingly.
Although the sample is only in Java, clients that share a session can write in any language that Web Services supports. For example, the session ID can be extracted by a Java client and consumed by a Perl client. If Perl is used for a re-use session, refer to the VI Perl Toolkit Programming Guide.1
Note that the session file format used in the VI Perl Toolkit is not simply the session ID string, but something more. The format of the session file is as follows:
#LWP-Cookies-1.0 Set-Cookie3: vmware_soap_session="\"52dc490b-a6e7-0e65-65a7-a926b924e72c\""; path="/"; domain=192.20.143.205; path_spec; discard; version=0
As mentioned, passing the session ID poses a security risk especially over the wire. The session ID is enough for a client to carry over all the privileges of the original user—whatever operation the user can do, the consumer client is able to do the same. This session cookie can also be used to access files over HTTP. Even worse, the session ID does not expire, so it allows enough time to prepare an attack. To avoid security issues, carefully consider whom to share a session with and how to send the session ID.