Skip to content

Single Sign On with Domino and WebSphere

Chapter 9-14
Single Sign-On with Domino and WebSphere

Single Sign-On with Domino and WebSphere

Domino provides a cryptographic token based mechanism to provide Single Sign-On support between protocols such as HTTP and DIIOP, and also with the IBM WebSphere application server. The servers that participate in Single Sign-On use an encrypted "Web SSO Configuration" to share secret data in the Domino Directory used for generating and validating Single Sign-On tokens. This secret information is used by the server to verify that the token presented by a user was generated by a server that shares the same secret.

WebSphere uses a format called Lightweight Third Party Authentication (LTPA), which was implemented in Domino in Release 5.0.5. Enabling Domino to interoperate with WebSphere for Single Sign-On. This requires generating the secret information within the WebSphere administration environment and then importing it into the Web SSO Configuration. Consult WebSphere product documentation for more information on configuring LTPA in WebSphere.

When interoperability with WebSphere is not required, Domino uses its own format for the Single Sign-On token that is slightly different from the one implemented by WebSphere. The servers participating in Domino Single Sign-On share a 20 byte secret that is used to generate and validate a SHA-1 hash that proves the integrity of the token. Details of the Domino Single Sign-On token format are covered below.

See the Domino Administrator's Guide for more details on configuring Single Sign-On.


Using the SECToken APIs

The Domino C API provides several functions that allow Domino C API applications to use Single Sign-On as an authentication mechanism. Domino itself uses these APIs to generate and validate Single Sign-On tokens for the HTTP and DIIOP server tasks. These tasks are configured to use a specific Web SSO Configuration, which can also be enabled to be part of an Organization (when using Domino 6 "Site Documents"). The SECToken APIs require the caller to specify a specific Configuration (and possibly Organization) from which the shared secrets used in generating and validating tokens are retrieved.

Server addin tasks that wish to implement their own authentication schemes can use these APIs to provide Single Sign-On using the token as an authentication credential, and also to interoperate with Domino protocols that support Single Sign-On.

For example, after an HTTP user is authenticated via name and password, SECTokenGenerate is called and returns the information necessary to store the Single Sign-On token in a browser cookie. The mhData member of the SSO_TOKEN structure is a MEMHANDLE to the BASE64 encoded Single Sign-On token. SECTokenGenerate also allows the caller to pass an optional expiration time to override the one specified in the Web SSO Configuration.

      /* Generate the token for the specified username.
      */
      error = SECTokenGenerate(NULL, "ORGNAME", "CONFIGNAME",
      szAuthName, NULL, NULL,
      &mhToken, 0, NULL);
      if (!error)
        {
        /* Lock the token structure and its member data.
        */
        pToken = (SSO_TOKEN*)OSMemoryLock(mhToken);
        pName = (char*)OSMemoryLock(pToken->mhName);
        pDomainList = (char*)OSMemoryLock(pToken->mhDomainList);
        pData = (char*)OSMemoryLock(pToken->mhData);

        /* return the data to the client in an appropriate manner
        * (IE: browser cookie for HTTP, session object for DIIOP)
        */
        ...
        /* Free the token memory.
        */
        SECTokenFree(&mhToken);
        }


See the C API Reference for more details on function parameters and returns.

When a token is present as a credential in an HTTP request header, SECTokenValidate is called to validate that the token was generated by a server sharing the same Web SSO Configuration and associated secret data. Encoded in the token is an authenticated name, and also the creation time and expiration time for the token. Note that the creation time is not encoded in the WebSphere format, and thus is not returned when validating a WebSphere LTPA token.

Any error returned from SECTokenValidate should be considered an authentication failure, and the parameters returned (Username and TimeDates) are only valid when there is no error (NOERROR) or when the token is expired (ERR_LTPA_TOKEN_EXPIRED). The parameter retUsername must be a buffer of size MAXUSERNAME.

    /* Validate the token data presented by the client.
    */
    error = SECTokenValidate(NULL, "ORGNAME", "CONFIGNAME",
       szTokenData, retAuthName,
                             &CreationTIMEDATE,
                             &ExpirationTIMEDATE,
       0, NULL);

    if (ERR_LTPA_TOKEN_EXPIRED == error)
    {
    /* Token is expired, handle appropriately.
    * (IE: redirect to login page for HTTP, displaying expiration)
    */
    ...
    {
    else if (ERR_LTPA_TOKEN_INVALID == error)
    {
    /* Token is cryptographically invalid, handle appropriately.
    * (IE: redirect to login page for HTTP)
    */
    ...
    }
    else if (error)
    {
    /* Some other lower level API error has occurred, handle appropriately.
    * (IE: server error 500 for HTTP)
    */
    ...
    }

    /* No error occurred, set the authenticated name and proceed
    * with authorization, etc.
    */
    ...


See the C API Reference for more details on function parameters and returns.


Implementing the Domino Single Sign-On token format

Applications that wish to participate in Single Sign-On with Domino's format, but do not have access to the Domino C API should be able to implement the format themselves, the only requirements are access to an implementation of BASE-64 encoding/decoding and an implementation of a SHA-1 hashing algorithm. This format of the Single Sign-On token is used by Domino only and does not interoperate with WebSphere's LTPA format for Single Sign-On.

The token itself is a BASE-64 encoded variable length byte stream that contains a versioning header, the creation time, expiration time, the username and a SHA-1 hash of the preceding data concatenated with the shared secret from the Web SSO Configuration.

The format of the Domino Single Sign-On token is as follows:

[token] = BASE64([header][creation time][expiration time][username][SHA-1 hash])

Where the SHA-1 hash is taken over the token data and the shared secret:

[SHA-1 hash] = SHA-1([header][creation time][expiration time][username][shared secret])

    To generate a Domino style Single Sign-On token

    1. Read the BASE-64 encoded secret data from the LTPA_DominoSecret field of the Web SSO Configuration.
    2. Read the expiration interval from the LTPA_TokenExpiration field of the Web SSO Configuration.
    2. Begin with the 4 bytes of versioning header information.
      - Version 0 is [0x00][0x01][0x02][0x03]
    3. Append the creation time.
      - Creation time is represented as an offset in seconds from 1/1/1970 12:00 GMT.
      - It is encoded as an 8 character hexadecimal string. Use printf() with the %08x modifier.
    4. Append the expiration time.
      - Expiration time is also represented as an offset in seconds from 1/1/1970 12:00 GMT.
      - It is encoded as a 8 character hexadecimal string. Use printf() with the %08x modifier.
    5. Append the Username.
      - There is no restriction on the format of the Username, but the LMBCS fully labeled canonical name is recommended, with a maximum length of MAXUSERNAME.
    6. Generate a SHA-1 hash (20 bytes) over the data that has been concatenated plus the 20 byte shared secret.
    7. Append the SHA-1 hash after the Username.
    8. BASE-64 encode the final token.

    To validate a Domino style Single Sign-On token

    1. Read the BASE-64 encoded secret data from the LTPA_DominoSecret field of the Web SSO Configuration.
    2. BASE-64 decode the token to its raw bytes.
    3. Calculate the length of the variable length data for the username.
      - variable_length = total_length - immutable_length (40 bytes)
      - The variable_length part of the token must be > 0. If not, the token is invalid.
    4. Verify the integrity of the token by checking the hash.
      - Generate a SHA-1 hash over the token (excluding the hash contained in the token) and the 20 byte shared secret.
      - Compare this hash to the one contained in the token. If they match, then the token is valid.
    5. Parse the first 4 bytes of header information.
      - Version 0 is [0x00][0x01][0x02][0x03]
    6. Parse the creation time.
    7. Parse and enforce the token expiration time.
    8. Parse the Username.

Debugging Single Sign-On

There is a debug NOTES.INI variable that is available to assist in tracing down problems with the encoding and decoding of Single Sign-On tokens. Set DEBUG_SSO_TRACE_LEVEL=1 to get information as the Web SSO Configuration is retrieved, and also as tokens are encoded and decoded. Set DEBUG_SSO_TRACE_LEVEL=2 to get more verbose memory dumps as tokens are encoded and decoded.