Home > Articles > Operating Systems, Server

  • Print
  • + Share This
This chapter is from the book

Using Single Sign-On from the VI SDK to CIM

When a client connects to the ESX server via the VI SDK, it has to log in. If it wants to further access the Common Information Model (CIM), it has to log in again using the same username and password. So the client has to either get input from users again or save the username/password somewhere. Neither of these two approaches is good for system security.

In some cases, like VI Client plug-in development, the Web application gets only the session string. It's impossible to get the password, which presumably can also be used for CIM access. So it is necessary for the VI SDK to provide a mechanism to issue tokens that can be used for CIM service login.

Starting with VI 3.5, VMware provides a new API to make possible single sign-on from the VI SDK to CIM. The following discusses how to get it done with sample Java code.

VI SDK 2.5 provides acquireCimServicesTicket() on a HostSystem managed object to get a HostServiceTicket object. The definition of the HostServiceTicket data object and related classes are shown in Figure 18-3. Some of its properties, such as host, port, and sslThumpprint, could be null because the API reference indicates "need not to be set."

Figure 18-3

Figure 18-3 The HostServiceTicket data object class and related classes

The sessionId is a string with a format as follows. It can be used as both username and password for CIM access login.

5259c389-9891-c650-b108-e10a0ff5c781

Now let's look at a Java program that shows how it can be done (see Listing 18-1).

Listing 18-1. CimTicket.java

package vim25.samples.mo.cim;
import java.net.URL;
import java.util.Enumeration;

import org.sblim.wbem.cim.CIMNameSpace;
import org.sblim.wbem.cim.CIMObject;
import org.sblim.wbem.cim.CIMObjectPath;
import org.sblim.wbem.client.CIMClient;
import org.sblim.wbem.client.PasswordCredential;
import org.sblim.wbem.client.UserPrincipal;

import com.vmware.vim25.HostServiceTicket;
import com.vmware.vim25.mo.Folder;
import com.vmware.vim25.mo.HostSystem;
import com.vmware.vim25.mo.InventoryNavigator;
import com.vmware.vim25.mo.ServiceInstance;

public class CimTicket
{
  public static void main(String[] args) throws Exception
  {
    if(args.length!=3)
    {
      System.out.println("Usage: java CimTicket <url> " +
          "<username> <password>");
      return;
    }
    String urlStr = args[0];
    String username = args[1];
    String password = args[2];

    ServiceInstance si = new ServiceInstance(new URL(urlStr),
        username, password, true);
    Folder rootFolder = si.getRootFolder();

    HostSystem host = (HostSystem) new InventoryNavigator(
        rootFolder).searchManagedEntities("HostSystem")[0];

    System.out.println(host.getName());
    HostServiceTicket ticket = host.acquireCimServicesTicket();
    System.out.println("\nHost Name:" + ticket.getHost());
    System.out.println("sessionId=" + ticket.getSessionId());
    System.out.println("sslThumpprint="
        + ticket.getSslThumbprint());
    System.out.println("serviceVersion="
        + ticket.getServiceVersion());
    System.out.println("service=" + ticket.getService());
    System.out.println("port=" + ticket.getPort());
    retrieveCimInfo(urlStr, ticket.getSessionId());
    si.getServerConnection().logout();
  }

  private static void retrieveCimInfo(
      String urlStr, String sessionId)
  {
    String serverUrl = urlStr.substring(0,
        urlStr.lastIndexOf("/sdk"));
    String cimAgentAddress = serverUrl + ":5989";
    String namespace = "root/cimv2";
    UserPrincipal userPr = new UserPrincipal(sessionId);
    PasswordCredential pwCred = new PasswordCredential(
        sessionId.toCharArray());

    CIMNameSpace ns = new CIMNameSpace(
        cimAgentAddress, namespace);
    CIMClient cimClient = new CIMClient(ns, userPr, pwCred);
    CIMObjectPath rpCOP = new CIMObjectPath(
        "CIM_RegisteredProfile");

    System.out.println("Looking for children of " +
        "CIM_RegisteredProfile");

    long enumerationStart = System.currentTimeMillis();
    Enumeration rpEnm = cimClient.enumerateInstances(rpCOP);
    long enumerationStop = System.currentTimeMillis();
    System.out.println("Enumeration completed in: " +
      (enumerationStop - enumerationStart) / 1000 + " sec.\n");

    while (rpEnm.hasMoreElements())
    {
      CIMObject rp = (CIMObject) rpEnm.nextElement();
      System.out.println(" Found: " + rp);
    }
  }
}

The console printout is shown here. Given the size limit, only the first several lines are listed:

test.acme.com
Host Name:test.acme.com
sessionId=5259c389-9891-c650-b108-e10a0ff5c781
sslThumpprint=null
serviceVersion=1.0
service=CimInterfaces
port=null
Looking for children of CIM_RegisteredProfile
Enumeration completed in: 0 sec.

 Found: instance of OMC_RegisteredSensorProfile {
      string AdvertiseTypeDescriptions[];

      uint16 AdvertiseTypes[] = {3};

      string Caption;

      string Description;

This API is supported by default in ESXi 3.5, but not in classic ESX. Users can manually enable it by tweaking a configuration file in classic ESX. In classic 3.5 U2, it's enabled as default. You can also use this API with VC server as long as the HostSystem it manages supports the feature.

The SBLIM Java client3 is used instead of the one4 used with the VI SDK CIM sample. The latter has a bug whereby it truncates the password after 16 characters, so it fails the CIM login.

  • + Share This
  • 🔖 Save To Your Account