vSphere uses single sign on to provide a single point of authentication for clients. vSphere includes the vCenter Single Sign On Server. To use vCenter Single Sign On, your client obtains a SAML token (Security Assertion Markup Language) from the vCenter Single Sign On Server and passes the token to the vCenter Server in the login request. The token represents the client and contains claims that support client authentication. Components in the vSphere environment perform operations based on the original authentication. For information about obtaining a vCenter Single Sign On token from the vCenter Single Sign On Server, see
vCenter Single Sign On Programming Guide.
To use single sign on, your client calls the LoginByToken method. Your client must send a SAML token to the vCenter Server by embedding the token in the SOAP header for the
LoginByToken request. During the login sequence, your client must save and restore the HTTP session cookie. The vCenter Single Sign On SDK contains sample code that demonstrates how to use the
LoginByToken method.
The following sections describe examples of using the LoginByToken method to establish a vCenter Single Sign On session with a vCenter Server.
After you obtain a SAML token from the vCenter Single Sign On Server, you can use the vSphere API method LoginByToken to establish a single sign on session with a vCenter Server. To establish a vCenter Server session that is based on SAML token authentication, the client must embed the SAML token in the SOAP header of the
LoginByToken request. The C#
LoginByToken example uses the following .NET services to support a single sign on session.
|
|
|
|
|
|
|
|
|
The sample uses the ConfigurationManager to specify certificate metadata (password and certificate type).
|
|
|
A persistent vCenter session relies on a session cookie. When the vCenter Server receives a connection request (
SessionManager.RetrieveServiceContent), the Server creates a session cookie and returns it in the HTTP header of the response. The client-side .NET framework embeds the cookie in HTTP messages that the client sends to the Server.
The LoginByToken request includes the SAML token and client certificate security assertions for client authentication. After successful login, the authentication overhead is no longer needed. The client resets the
VimService context to eliminate the security overhead. Subsequent client requests will contain the session cookie, which is enough to support the persistent, authenticated session.
The code examples in the following sections show how to use the LoginByToken method with a holder-of-key security token. The code examples are based on the
LoginByTokenSample project contained in the vCenter Single Sign On SDK. The project is located in the
dotnet samples directory (
SDK/ssoclient/dotnet/cs/samples/LoginByToken).
The LoginByTokenSample class constructor creates the following elements to set up access to the vCenter Server.
■
|
VimService object – Provides access to vSphere API methods and support for security policies and session cookie managment. It also stores the vCenter Server URL.
|
■
|
ManagedObjectReference – Manually created ManagedObjectReference to retrieve a ServiceInstance at the beginning of the session.
|
The LoginByToken sample creates a custom policy assertion that is derived from the .NET class
SecurityPolicyAssertion. The assertion class gives the .NET framework access to the SAML token and the X509 certificate.
■
|
Sets the ServicePointManager properties to specify SSL3 and HTTP 100-Continue response handling. 100-Continue response handling supports more efficient communication between the client and vCenter Server. When the client-side .NET framework sends a request to the Server, it sends the request header and waits for a 100-Continue response from the Server. After it receives that response, it sends the request body to the Server.
|
■
|
Creates an X509Certificate2 object, specifies the certificate file, and imports the certificate. The certificate file specification indicates a PKCS #12 format file (Public-Key Cryptography Standards) – PfxCertificateFile. The file contains the client’s private key and public certificate. The PfxCertificateFile setting is defined in the app.config file in the LoginByToken project. The definition specifies the location of the file.
|
The following code fragment shows the LoginByTokenSample class method
GetSecurityPolicyAssertionForHokToken. The method returns a
CustomSecurityAssertionHok instance which overrides the .NET class
SecurityPolicyAssertion. The security assertion contains the SAML token and the X509 certificate token. This code is taken from the
LoginByToken project file
samples/LoginByToken/CustomSecurityAssertionHok.cs.
■
|
SecureMessage – An override method for the .NET method SendSecurityFilter.SecureMessage. The override method adds the SAML token and message signature to the .NET Security element.
|
xmlns=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd""
wsse:TokenType=""http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLV2.0"">
<KeyIdentifier xmlns=""http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd""
ValueType=""http://docs.oasis-open.org/wss/oasis-wss-saml-token-profile-1.1#SAMLID"">" + samlAssertionId +
■
|
Calls the LoginByTokenSample class method GetSecurityPolicyAssertionForHokToken (see Security Policies) and adds the security policy to the VimService object.
|
The VimService object contains the following data:
■
|
Calls the RetrieveServiceContent method. The method establishes the connection with the vCenter Server and it returns a session cookie. The session cookie is stored in the cookie container in the VimService object.
|
■
|
Calls the LoginByToken method. The .NET framework uses the security policy assertion and the session cookie to construct the login request.
|
■
|
Calls the LoginByTokenSample class method resetService to create a new VimService object.
|
The following code fragment shows the resetService method. The method creates a new
VimService object and a new cookie container. The method also obtains a new instance of the session cookie.
The following example is based on the LoginByTokenSample.java file contained in the vCenter Single Sign On SDK. The SDK contains Java code that supports HTTP and SOAP header manipulation.
After you obtain a SAML token from the vCenter Single Sign On Server, you can use the vSphere API method LoginByToken to establish a vCenter Single Sign On session with a vCenter Server. At the beginning of the session, your client is responsible for the following tasks:
1
|
Call the RetrieveServiceContent method to establish an HTTP connection with the vCenter Server and save the HTTP session cookie. The client uses an HTTP header handler method to extract the cookie from the vCenter Server response.
|
2
|
Call the LoginByToken method to authenticate the vCenter session. To send the token to the vCenter Server, the client uses a handler to embed the token and a time stamp in the SOAP header for the message. To identify the session started with the RetrieveServiceContent method, the client uses a handler to embed the session cookie in the HTTP header.
|
To use a vCenter Single Sign On token to login to a vCenter Server, the example uses header handlers to manipulates the HTTP and SOAP header elements of the login request. After establishing a handler, subsequent requests automatically invoke the handler.
Important Every call to the vCenter Server will invoke any message handlers that have been established. The overhead involved in using the SOAP and HTTP message handlers is not necessary after the session has been established. The example saves the default message handler before setting up the SOAP and HTTP handlers. After establishing the session, the example will reset the handler chain and restore the default handler.
The example code also uses multiple calls to the VimPortType.getVimPort method to manage the request context. The getVimPort method clears the HTTP request context. After each call to the getVimPort method, the client resets the request context endpoint address to the vCenter Server URL. After the client has obtained the session cookie, it will restore the cookie in subsequent requests.
|
The code examples in the following sections show how to use the LoginByToken method with a holder-of-key security token. The code examples are based on the sample code contained in the vCenter Single Sign On SDK. The files are located in the Java samples directory (
SDK/ssoclient/java/JAXWS/samples):
vimService = new VimService();
SVC_INST_REF.setType("ServiceInstance");
SVC_INST_REF.setValue("ServiceInstance");
HeaderCookieExtractionHandler cookieExtractor = new HeaderCookieExtractionHandler();
HeaderHandlerResolver handlerResolver = new HeaderHandlerResolver();
handlerResolver.addHandler(cookieExtractor);
vimService.setHandlerResolver(handlerResolver);
vimPort = vimService.getVimPort();
Map<String, Object> ctxt = ((BindingProvider) vimPort) .getRequestContext();
ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, vcServerUrl);
ctxt.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);
serviceContent = vimPort.retrieveServiceContent(SVC_INST_REF);
String cookie = cookieExtractor.getCookie();
The code fragment in this section sets up the message handlers and calls the LoginByToken method. The following sequence describes the steps and shows the corresponding objects and methods.
handlerResolver.addHandler(new TimeStampHandler());
handlerResolver.addHandler(new SamlTokenHandler(token));
handlerResolver.addHandler(new HeaderCookieHandler(cookie));
handlerResolver.addHandler(new WsSecuritySignatureAssertionHandler(
userCert.getPrivateKey(),
userCert.getUserCert(),
Utils .getNodeProperty(token, "ID")));
vimService.setHandlerResolver(handlerResolver);
vimPort = vimService.getVimPort();
Map<String, Object> ctxt = ((BindingProvider) vimPort) .getRequestContext();
ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, vcServerUrl);
ctxt.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);
UserSession us = vimPort.loginByToken( serviceContent.getSessionManager(), null);
After you log in, you must restore the standard vCenter session context. The code fragment in this section restores the default message handler and the session cookie. As the cookie handler has been replaced by the default handler, the client resets the session cookie by calling request context methods to access the context fields directly. The following sequence describes these steps and shows the corresponding objects and methods.
vimService.setHandlerResolver(defaultHandler);
vimPort = vimService.getVimPort();
// Set the validated session cookie and set it in the header for once,
// JAXWS will maintain that cookie for all the subsequent requests
Map<String, Object> ctxt = ((BindingProvider) vimPort) .getRequestContext();
ctxt.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, vcServerUrl);
ctxt.put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);
Map<String, List<String>> headers = (Map<String, List<String>>) ctxt.get(MessageContext.HTTP_REQUEST_HEADERS);
headers = new HashMap<String, List<String>>();
ctxt.put(MessageContext.HTTP_REQUEST_HEADERS, headers);