When a plug-in server communicates with vCenter Server, it must authenticate to act on behalf of the user. This procedure shows how to delegate authority from the plug-in client code, running in a browser, to the remote plug-in server.

Before the plug-in server can establish a session with a vCenter Server, it must know the endpoint attributes for that instance. A best practice is to maintain a configuration file, for each plug-in server, that stores the attributes for each vCenter Server instance where the plug-in is registered. For example, a JSON representation of endpoint attributes might look similar to this:
{
  "vc1-guid": {
    "fqdn": "vc1.example.com",
    "thumbprint": "vc1-thumbprint",
    "port": 443
  },
  "vc2-guid": {
    "fqdn": "vc2.example.com",
    "thumbprint": "vc2-thumbprint",
    "port": 443
  }
}

In its simplest form, the delegation procedure involves communications between a plug-in front end and its sandbox environment, between the plug-in front end and the plug-in back end, and between the back end and an instance of vCenter Server. In some situations, two or three vCenter Server instances participate in the delegation procedure. The following orientation diagram shows all the processes that might work together to delegate session authority securely to the plug-in back end.

This diagram introduces the components involved in delegating server authority.

Use the following steps to delegate authority from the plug-in front end code to the plug-in server. The plug-in server can use this procedure to establish a session with any vCenter Server instance in the same ELM link group.
  1. The plug-in user interface calls the app.getSessioninfo() method in the client JavaScript library, which in turn contacts the plug-in sandbox to request session information. The sandbox returns an object containing a sessionToken string, which contains a new plug-in session token that can be used for authentication by the plug-in server. The token represents the authority of the session the user established between the vSphere Client and the vCenter Server instance to which it is connected.

    This diagram shows step 1 of the delegation sequence.

  2. The plug-in user interface calls the app.getContextObjects() method in the client JavaScript library, which returns the ID of the object currently selected in the vSphere Client. The object ID is appended with the GUID of the vCenter Server instance that manages the object. The vCenter Server GUID is the substring following the last colon separator (:).

    This diagram shows step 2 of the delegation sequence.

    Note: If a global view is active instead of an object view, app.getContextObjects() returns an empty list.
  3. The plug-in user interface extracts both the session key and the vCenter Server GUID, then sends them to the plug-in server, using a custom API.
    Note: If no GUID is available, the plug-in user interface sends only the session key.

    This diagram shows step 3 of the delegation sequence.

  4. The plug-in back end builds a REST request to the vsphere-ui service of a vCenter Server instance. The request contains the following:
    • A POST verb
    • The clone-ticket endpoint path: /api/ui/vcenter/session/clone-ticket
    • The Content-type and Accept headers both set to application/json.
    • A custom header named vmware-api-session-id, with the session token as its value
    • A JSON object body, containing a vc-guid property whose value is the GUID of the vCenter Server instance
    This diagram shows step 4 of hte delegation sequence.

    The request will look similar to this:

    POST /api/ui/vcenter/session/clone-ticket
    Content-type: application/json
    Accept: application/json
    vmware-api-session-id: 12345678
    
    {
      "vc_guid": "223b94f2-af15-4613-5d1a-a278b19abc09"
    }
  5. The plug-in back end sends the REST request to the clone-ticket REST endpoint of any vCenter Server instance, by using the endpoint attributes in the plug-in server configuration data.

    This diagram shows step 5 of the delegation sequence.

    In some cases, this can trigger extra back-end communications before the plug-in back end receives a reply. For example:

    1. The plug-in back end might be sending the request to a vCenter Server instance that does not hold the user session, particularly if the user's browser is connected to an instance with which the plug-in is not registered. In that case, the reverse HTTP proxy forwards the request to the vCenter Server instance that holds the user session.

      In the following diagram, the browser is connected to VC1, which serves the vSphere Client in the browser. The plug-in back end chooses to contact VC2 with the clone-ticket request. VC2 forwards the request to VC1, which holds the session key.

      .

      This diagram shows variant a of step 5 of the delegation sequence.

    2. The context object the user selected might be on a third vCenter Server instance. In that case, the vSphere Client back end (the vsphere-ui process) issues a Web Services API call to the vCenter Server instance identified by the GUID in the clone-ticket request. The vsphere-ui process uses the acquireCloneTicket() method of the SessionManager managed object to request delegation of session authority to the process that presents the ticket to the vCenter Server instance.

      In the following diagram, VC2 forwards the clone-ticket request to VC1, which holds the session with the vSphere Client in the browser. VC1 discovers that the context object is managed by VC3, so VC1 requests a clone ticket that will allow the plug-in back end to authenticate with VC3.

      This diagram shows variant b of step 5 of the delegation sequence.

    3. The call chain returns the ticket to the plug-in back end. The ticket gives the plug-in back end a means to establish a Web Services session with VC3.

      This diagram shows variant c of step 5 of the delegation sequence.

    The clone ticket is valid for the Web Services API of the vCenter Server instance associated with the context object. This is a single-use key to authenticate a call to the SessionManager.

    The response will look similar to this:

    {
      "session_clone_ticket": "cst-VCT-82cbd981-5f52-0a67-fe55-d995a7347f82--tp-B6-BC-CB-B8-59-89-C0-F2-E4-F0-C2-91-8F-28-C1-DE-10-5E-24-69"
    }
  6. The plug-in back end constructs a SOAP request to obtain a regular session ID from the Web Services API, by using the cloneSession() operation on the Session Manager.

    This diagram shows step 6 of the delegation sequence.

    The code for the SOAP request will be similar to this Java example:

    VimService vimService = new VimService();
    VimPortType client = vimService.getVimPort();
    ManagedObjectReference siRef = new ManagedObjectReference();
    siRef.setType("ServiceInstance");
    siRef.setValue("Serviceinstance");
    ServiceInstance si = client.createStub(ServiceInstance.class, siRef);
    ServiceInstanceContent sic = si.RetrieveContent();
    SessionManager mgr = client.createStub(SessionManager.class, sic.getSessionManager());
    UserSession wsSession = mgr.cloneSession(sessionCloneTicket);
  7. The cloneSession() method retrieves a new multi-use session key and applies it to the linked VimPort object. Subsequent SOAP requests sent by means of the same VimPort object authenticate with the new session key.

    This diagram shows step 7 of the delegation sequence.