Using Tivoli Access Manager for eBusiness WebSEAL without a user registry

Leveraging Tivoli Federated Identity Manager to remove the need for a user registry for TAMeB and WebSEAL

Often customers require a Web single sign-on and authorization solution but are unable or unwilling to replace or synchronize their existing user registry with another. This can pose a problem for customers wanting to leverage IBM® Tivoli® Access Manager for eBusiness (TAMeB) where their existing user registry is not supported natively by TAMeB. This article demonstrates how to utilize Tivoli Access Manager for eBusiness WebSEAL without requiring enterprise users to be in the TAMeB directory. This article requires some prior knowledge of Tivoli Access Manager for eBusiness authentication, the TAMeB external authentication interface (EAI), and the Tivoli Federated Identity Manager (TFIM) Security Token Service (STS).

Share:

Shane B. Weeden, Senior Software Engineer, IBM

Shane WeedenShane Weeden is a senior software engineer with the IBM Tivoli Federated Identity Manager development team. He has worked in IT security since 1992, and since 2000 has been working with Tivoli Security products including Tivoli Access Manager for eBusiness and Tivoli Federated Identity Manager. Shane now divides his time between customer focused engagements and core product development activities. He holds a Bachelor of Information Technology from the University of Queensland in Australia.



03 February 2009

Prequisite Knowledge

This article assumes a basic familiarity with:

  • Tivoli Access Manager for eBusiness WebSEAL
  • The WebSEAL external authentication interface (EAI)
  • The Tivoli Federated Identity Manager runtime, including the Security Token Service
  • J2EE and Java™ programming of servlets

To implement and deploy the scenario described in this article, you need a configured TAMeB WebSEAL server, and a configured Tivoli Federated Identity Manager runtime.

Stay ahead of insider threats with predictive, intelligent security

Stay ahead of insider threats with predictive, intelligent security

In this paper, we discuss ways to identify and protect against internal threats through a combination of robust foundational controls, intelligent reporting, and management tools. Read the whitepaper to learn about:

  • The evolution of insider threats
  • Intelligent security systems for combating insider threats.
  • Ways to enhance security with intelligence and big data analytics.

Download "Stay ahead of insider threats with predictive, intelligent security."

Overview of the solution

The solution architecture for using WebSEAL without a dedicated TAMeB user registry leverages a particular feature of the TAMeB external authentication interface (EAI). EAI allows an external application (that is, external to the WebSEAL process) to perform user authentication (for example, by comparing a supplied username and password against a database), and then return the authenticated user and attribute data to WebSEAL via a set of response HTTP headers to effect a login. WebSEAL then builds and manages a Web HTTP session for the user. There are two different formats that an EAI application can use to return authenticated user and attribute data:

  • Simple, separate text headers conveying the short TAMeB username for the user and other extended attributes. In this case, WebSEAL performs a lookup of the user registry for a user record with the given username, then builds a credential (that is, extended privilege attribute certificate (EPAC)) from that username and inserts the other extended attributes into that credential. With this method the user must be part of the TAMeB user registry.
  • An encoded cxtended privilege attribute certificate (EPAC). In this case an encoded EPAC (a proprietary encoding format for a TAMeB user credential) is returned to WebSEAL in a single HTTP header. When WebSEAL receives a fully encoded EPAC in an EAI header it does not consult the user registry - instead it creates a user session and populates it directly with the EPAC supplied from the EAI. This is the authentication technique for WebSEAL that applies to the theme of this article as it does not require the users to be in the directory.

TAMeB authorization APIs for credentials

This is actually the SAME set of APIs that WebSEAL uses when building an EPAC from the text-based username and attribute EAI headers. In our scenario these APIs are no help as they still require the user to exist in the TAMeB user registry.

The next question is then - how does one build an EPAC? TAMeB provides a set of public APIs (Java and C) to allow customers to build and modify an EPAC, however these APIs also require consultation of the TAMeB configured user registry.

Fortunately there is another method available to build a TAMeB EPAC that does not require consultation of the TAMeB user registry. This alternate solution makes use of the Tivoli Federated Identity Manager (TFIM) Security Token Service (STS).

The TFIM STS is a Web service that supports the WS-Trust 1.2 and 1.3 specifications for the validation and exchange of security tokens. Natively, TFIM is able to build a TAMeB EPAC withouth consulting the TAMeB user registry. The following sections outline in detail how a solution can be developed to authenticate a user to WebSEAL without the user being in the TAMeB registry using this native capability of TFIM.

The overall architecture of the solution is shown in Figure 1:

Figure 1. Solution architecture
Solution architecture

The workflow is as follows:

  1. An initially unauthenticated user attempts to access a protected resource, and is sent the WebSEAL login page. The login page POSTs data to the EAI application.
  2. The EAI application receives the authentication data (could be simply a username and password), and validates this against the existing user registry. The net result of this step is that the EAI application now knows who the user is, and any other attribute data (for example, group memberships, personal attributes) that applications (or even WebSEAL) might need.
  3. The EAI application now constructs a simple user token called an STSUniversalUser using TFIM-provided APIs. Required attributes can be added programmatically to this token.
  4. TFIM ships an STS client API (originally from the Higgins Open Source Identity Framework) to call the TFIM STS. The TFIM STS exchanges the STSUniversalUser for a TAMeB credential using a Trust Chain configured for this purpose.
  5. The EAI application receives an IV-Cred token (EPAC) from the TFIM STS and converts this into a HTTP response header.
  6. WebSEAL creates a user session based on the EPAC and redirects the (now authenticated) user to their desired, protected resource (as in step 1).
  7. WebSEAL recognizes the user is authenticated, performs necessary authorization checks and grants access to the resource.

The WebSEAL single sign-on capabilities to junctioned applications (using basic-authentication, the iv-user header, forms-based SSO, etc) work just as they do when all users are stored in the TAMeB User Registry. However special consideration needs to be made for WebSEAL authorization, because this approach of building the credential does not provide information in the credential for traditional authorization checks using access control lists (ACLs). Two primary approaches are possible and discussed later in this article - using authorization rules, and using actual TAMeB groups.

The remainder of this article describes the development and configuration necessary to implement and test the solution. The starting point for developing and deploying the solution is a configured installation of Tivoli Access Manager for eBusiness WebSEAL, and the Tivoli Federated Identity Manager runtime. A WebSphere® server should be available to run the EAI application. This can be the same WebSphere server as used for the TFIM runtime.

Development of the EAI application

The Downloads section contains an example EAI application that you can use as a starting point for developing the EAI. First import the EAR file into an Eclipse development environment, and open the servlet class com.ibm.demo.EAIServlet.

The source code from this class is shown in Listing 1:

Listing 1. EAIServlet
package com.ibm.demo;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.ibm.tivoli.fim.sts.client.IRequestSecurityToken;
import com.ibm.tivoli.fim.sts.client.IRequestSecurityTokenResponse;
import com.ibm.tivoli.fim.sts.client.IStsClient;
import com.ibm.tivoli.fim.sts.client.StsClientFactory;
import com.ibm.tivoli.fim.sts.client.higgins.StsHigginsClientConstants;
import com.tivoli.am.fim.trustserver.sts.STSUniversalUser;
import com.tivoli.am.fim.trustserver.sts.uuser.Attribute;

/**
 * The EAIServlet class is an example template from which you can build your
 * own EAI that uses the TFIM STS to construct TAMeB credentials. It does not
 * perform authenticaiton (just uses a canned username), and its
 * sole purpose is to illustrate how to construct an STSUniversalUser and
 * exchange it at the TFIM STS for a TAMeB credential.
 *
 *
 */
public class EAIServlet extends HttpServlet {

  private static final long serialVersionUID = 1L;

  private static String CLASSNAME = EAIServlet.class.getName();

  private static Logger _log = Logger.getLogger(CLASSNAME);

  Map _stsConfig;

  String _issuer = null;

  String _applies_to = null;

  /**
   * An initialization method. The primary purpose of this method is to
   * establish some init parameters for the STS client. You can choose to do
   * this a completely different way - for example, from ServletConfig parameters.
   */
  public void init() throws ServletException {
    String methodName = "init";
    _log.entering(CLASSNAME, methodName);
    try {
      super.init();
      _stsConfig = new HashMap();

      // initialize from here, or from servlet config, however you like
      _stsConfig.put("sts.endpoint.url",
        "http://localhost:9080/TrustServer/SecurityTokenService");
      _stsConfig.put("enable.must.understand", "false");
      _applies_to = "http://appliesto/ivcred";
      _issuer = "http://issuer/stsuu";
    } finally {
      _log.exiting(CLASSNAME, methodName);
    }
  }

  /**
   * The main entry point into the EAIServlet. This method should read input
   * parameters and perform authentication (the example just uses a canned
   * username and skips authentication), then exchange the determined username
   * and attributes for a TAMeB credential using the TFIM Security Token
   * Service. The resulting TAMeB credential is returned in an EAI header to
   * authenticate to WebSEAL.
   */
  protected void doGet(HttpServletRequest req, HttpServletResponse rsp)
    throws ServletException, IOException {
    String methodName = "doGet";
    _log.entering(CLASSNAME, methodName);
    try {
      // authenticate the user however you want
      String authenticated_user = "shane";

      /*
       * Build an STSUU representing this user (with attributes if you
       * like, as shown)
       */
      STSUniversalUser stsuu = new STSUniversalUser();
      stsuu.setPrincipalName(authenticated_user);
      stsuu.addAttribute(new Attribute("position", null,
        new String[] { "senior software engineer" }));
      stsuu.addAttribute(new Attribute("usergroups", null, new String[] {
        "group1", "group3" }));

      // do a WS-Trust exchange of STSUU for IV-Cred
      String epac = doSTSExchange(stsuu);

      if (epac != null) {
        rsp.setHeader("am-fim-eai-pac", epac);

        // you may set the EAI redirection URL header if you like
        //rsp.setHeader("am-fim-eai-redir-url", "/cgi-bin/epac");
      } else {
        throw new ServletException("Unable to perform STS exchange");
      }
    } finally {
      _log.exiting(CLASSNAME, methodName);
    }
  }

  protected void doPost(HttpServletRequest req, HttpServletResponse rsp)
    throws ServletException, IOException {
    // don't care about request method - do same as "doGet()"
    doGet(req, rsp);
  }

  /**
   * This is the main demonstration function of the EAIServlet - exchanging an
   * STSUniversalUser for a TAMeB credential string, which can be used as an EAI
   * response header.
   */
  String doSTSExchange(STSUniversalUser stsuu) {
    String methodName = "doSTSExchange";
    String result = null;
    _log.entering(CLASSNAME, methodName);
    try {
      /*
       * Initialization - get the STS objects we need to use
       */
      StsHigginsClientConstants constants = new StsHigginsClientConstants();
      IStsClient client = StsClientFactory.getStsClientInstance(_stsConfig);
      IRequestSecurityToken req = StsClientFactory.getRequestSecurityTokenInstance();

      /*
       * Set all the request properties for the RequestSecurityToken
       */
      req.setAppliesToAddress(new URI(_applies_to));
      req.setIssuerAddress(new URI(_issuer));
      req.setRequestType(constants.getValidateRequestType());
      req.setSecurityToken(stsuu.toXML().getDocumentElement());

      /*
       * Send the request, and get a response.
       */
      IRequestSecurityTokenResponse rsp = client.sendRequest(req);

      /*
       * If we got a valid response, extract the TAMeB credential and remove
       * embedded newline characters.
       */
      if (rsp != null) {
        result = stripNewlines(rsp.getRequestedSecurityToken().getTextContent());
      }

    } catch (URISyntaxException ue) {
      // should not happen unless you use invalid applies-to or issuer URI's
      ue.printStackTrace();
      result = null;
    } finally {
      _log.exiting(CLASSNAME, methodName, result);
    }
    return result;
  }

  /**
   * The returned TAMeB credential token contains embedded newline characters -
   * this is used to remove them.
   */
  String stripNewlines(String credToken) {
    String result = credToken.replaceAll("\n", "");
    return result;
  }
}

Note that in this example there is no authentication of user data performed. Instead that step is skipped, and the authenticated user "shane" is assumed.

There are two primary components of the servlet - the init method where initialization of constants is performed, and the doGet method where requests are processed.

The init() method

You might want to change the code in the init method to read configuration from ServletConfig parameters, a configuration file, and so on, so long as the configuration matches the STS location and trust chain parameters within TFIM. Notice that in this article the STS endpoint URL is http://localhost:9080/TrustServer/SecurityTokenService, indicating that the servlet is installed on the same WebSphere server as the TFIM runtime. The URL points to the WS-Trust 1.2 endpoint of TFIM.

The doGet() method

This method must authenticate to the enterprise user store. In this example the user is assumed to be 'shane', and a simple STSUniversalUser token is built using the TFIM APIs. This STSUniversalUser contains the username and two example extended attributes (position and usergroups). The STSUniversalUser token is then exchanged at the TFIM STS for a TAMeB credential token. The TAMeB credential token returned from the TFIM STS contains embedded newline characters, which are then removed before converting the EPAC to a single long string. This value is then returned as an EAI response header that needs to match the WebSEAL configuration for header names. The WebSEAL configuration is shown later in this article.

The credential

The example code in Listing 1 generates a credential that has very simple attributes. The WebSEAL epac demonstration application can be used to display the contents of a credential, as can the JSP in this developerWorks tutorial. Figure 2 shows an epac demonstration application screenshot of the credential created with the servlet code from Listing 1:

Figure 2. User credential
User credential

Note in Figure 2 the position and usergroups attributes are referenced later in this article.

TAMeB / WebSEAL configuration for EAI

The configuration for the TAMeB / WebSEAL environment consists of:

  • Configuration of the WebSEAL configuration file for EAI authentication
  • Creating a WebSEAL junction to the application server hosting the EAI application
  • Attaching a TAMeB ACL that allows unauthenticated access to the junctioned EAI application
  • Applying authorization constraints to the applications that are accessed by authenticated users

WebSEAL configuration for EAI authentication

The WebSEAL Administration Guide contains detailed technical information on EAI authentication here. This section summarizes the key steps for enabling EAI authentication. These changes consist of updates to the webseald-<instance>.conf file, and the summary of changes is shown in Listing 2:

Listing 2. WebSEAL configuration file changes for EAI authentication
[eai]
# HTTPS recommended for EAI as sensitive authentication information
# typically posted in forms
eai-auth = https

# Header variables - note that these match those used by default for the TFIM runtime
eai-pac-header = am-fim-eai-pac
eai-pac-svc-header = am-eai-pac-svc
eai-user-id-header = am-fim-eai-user-id
eai-auth-level-header = am-eai-auth-level
eai-xattrs-header = am-eai-xattrs
eai-redir-url-header = am-fim-eai-redir-url

# Indicates that any login with a PAC completely replaces existing login credential
retain-eai-session = no


[eai-trigger-urls]
# The trigger URL for the EAI application. Note that /jct below should be replaced
# with your junction to the application server running the EAIServlet.
trigger = /jct/EAISTS/EAIServlet

[authentication-mechanisms]
# Change according to your particular platform - this example is for Linux.
ext-auth-interface = /opt/pdwebrte/lib/libeaiauthn.so

WebSEAL junction to the EAI application server

The junction to the WebSphere server running the EAI servlet might already exist (for example, if there is a TFIM runtime deployment, and that is where you are hosting the EAI servlet) or you might need to manually create it. If you need to manually create it, Listing 3 shows the recommended command format with the pdadmin command line utility:

Listing 3. WebSEAL junction
pdadmin> server task <server_name> create -t tcp -c all -h localhost -p 9080 /jct

TAMeB access control list for EAI

In this example the EAI application must be authorized for access by an unauthenticated user. The access control list (and attachment) shown in Listing 4 can be used as an example of setting the policy to allow unauthenticated access:

Listing 4. Allowing unauthenticated access to the EAI application
pdadmin> acl create unauth
pdadmin> acl modify unauth set group iv-admin TcmdbsvaBRrxl
pdadmin> acl modify unauth set group webseal-servers Tgmdbsrxl
pdadmin> acl modify unauth set user sec_master TcmdbsvaBRrxl
pdadmin> acl modify unauth set any-other Trx
pdadmin> acl modify unauth set unauthenticated Trx

pdadmin> acl attach /WebSEAL/<server_root>/jct/EAISTS/EAIServlet unauth

Authorization policy templates

After a user has been authenticated with the EAIServlet, there can be conditional authorization requirements that need to be enforced for particular applications. At the simplest level, it might be that all applications can be accessed by anyone that is authenticated, and in that case the use of the basic default-webseal ACL is all that is required. However when more selective authorization is required, additional configuration needs to be performed.

In a traditional TAMeB deployment with all enterprise users in the TAMeB user registry, the most common form of authorization policy template that is used is the TAMeB ACL. The ACL entries rely on users and groups in the TAMeB registry. These users and groups have a universally unique identifer (UUID) associated with them, which is known by both the TAMeB authentication APIs when building a credential from the registry and by the authorization database when an ACL is created. When an ACL authorization check is made at runtime, the user credential's user and group UUIDs are compared with those in the ACL database. In the type of credential built in this article, there are no associated UUIDs. Hence TAMeB ACLs are not an appropriate form of authorization policy template to use for fine-grained authorization.

It is far more likely that the right authorization policy template to use in this type of deployment is the TAMeB authorization rule, written as an Extensible Stylesheet Template (XSLT). More information about TAMeB authorization rules can be found here in the TAMeB administration documentation. What follows in Listing 5 is a simple example rule that will allow anyone with the credential attribute called 'position' with the value 'senior software engineer' to have access. Note that this matches the attribute added to the example user credential in the EAIServlet in Listing 1.

Listing 5. Example authorization rule for senior software engineers
<xsl:choose>
  <xsl:when test="position = 'senior software engineer'">!TRUE!</xsl:when>
  <xsl:otherwise>!FALSE!</xsl:otherwise>
</xsl:choose>

To create the authorization rule, first create a simple text file with the above text (for example, /tmp/myrule.txt), then use the pdadmin commands shown in Listing 6 as a guide. The command shown assumes a WebSEAL junction to the target application called /appjct:

Listing 6. Creating and applying an authorization rule
pdadmin> authzrule create myrule -rulefile /tmp/myrule.txt
pdadmin> authzrule attach /WebSEAL/<server_root>/appjct myrule

Note that attributes can also be multi-valued, and authorization rules statements can be more complex. Consider the usergroups attribute in the credential from Figure 2. If you need to allow users in the usergroups of either group1 or group2, an authorization rule like that shown in Listing 7 can be used:

Listing 7. Example authorization rule for group1 or group2
<xsl:choose>
  <xsl:when test="usergroups = 'group1' or usergroups = 'group2'">!TRUE!</xsl:when>
  <xsl:otherwise>!FALSE!</xsl:otherwise>
</xsl:choose>

The example code from Listing 1 will also satisfy this rule as the user has the attribute value group1 in its multi-valued list. Arbitrarily complex authorization rules can be developed by expanding on these examples depending on the set of attributes set in the credential from the EAI servlet.

TFIM configuration of the IVCred module and STS chain

The TFIM configuration for this solution consists of two primary components:

  • The modification of the IVCred module instance to build TAMeB credentials without needing to communicate with the TAMeB authorization server (and hence the TAMeB user registry).
  • The creation of a TFIM STS chain to convert the simple STSUniversalUser XML token to a TAMeB credential.

Each of these steps is covered in detail in following subsections.

Modify IVCred token module instance

By default the Default IVCred Module Instance in TFIM issues a TAMeB credential by first contacting the TAMeB authorization server (also known as pdacld) to build a skeleton credential from the user's name. This includes the groups (and their UUID's) for that user as defined in the TAMeB user registry. To configure TFIM to not use the TAMeB authorization server for building TAMeB credentials, perform the following steps using the TFIM console:

Navigate to Tivoli Federated Identity Manger->Configure Trust Service->Module Instances, as shown in Figure 3:

Figure 3. STS Module Instances
STS Module Instances

Select the checkbox next to the Default IVCred Token, and click Properties, as shown in Figure 4:

Figure 4. Select Default IVCred Token
Select Default IVCred Token

Unselect the checkbox next to the text Enable Access Manager (IVCred) credential issuing (requires PDJRTE to be configured), and click OK, as shown in Figure 5:

Figure 5. IVCred Token Properties
IVCred Token Properties

After completing the configuration change, click Load Configuration changes to the TFIM Runtime.

Create STS chain

The remaining TFIM configuration requirement is to create an STS chain that converts an STSUniversalUser token into a TAMeB Credential token. No identity mapping step is required in this case, because all the required parameters are prepared directly from the EAIServlet. The TFIM STS is used to do a token conversion. The steps required to create the desired STS chain are as follows:

Navigate to Tivoli Federated Identity Manger->Configure Trust Service->Trust Service Chains, then click Create. The Trust Service Chain Mapping Wizard should appear, as shown in Figure 6:

Figure 6. Trust Service Chain Mapping Wizard - Step 1
Trust Service Chain Mapping Wizard - Step 1

Select Next, then enter a Chain Mapping Name and Description, as shown in Figure 7:

Figure 7. Trust Service Chain Mapping Wizard - Step 2
Trust Service Chain Mapping Wizard - Step 2

Select Next, then enter Chain Mapping Lookup properties, as shown in Figure 8:

Figure 8. Trust Service Chain Mapping Wizard - Step 3
Trust Service Chain Mapping Wizard - Step 3

Select Next, then enter Chain Identification properties, as shown in Figure 9:

Figure 9. Trust Service Chain Mapping Wizard - Step 4
Trust Service Chain Mapping Wizard - Step 4

Select Next, then use the Chain Assembly panel to add the Default STSUU token in validate mode, followed by the Default IVCred Token in issue mode, as shown in Figure 10:

Figure 10. Trust Service Chain Mapping Wizard - Step 5
Trust Service Chain Mapping Wizard - Step 5

Click Next, then click Continue to bypass the warning about the recommended chain structure. The next panel will be the configuration properties for the STSUniversalUser token module (there are none), so click Next to go to the configuration properties for the Access Manager Credential Module, as shown in Figure 11:

Figure 11. Trust Service Chain Mapping Wizard - Step 6
Trust Service Chain Mapping Wizard - Step 6

These can be left at the defaults, so click Next to go to the Chain Summary panel, as shown in Figure 12:

Figure 12. Trust Service Chain Mapping Wizard - Step 7
Trust Service Chain Mapping Wizard - Step 7

Click Finish to save the chain, then click Load configuration changes to Tivoli Federated Identity Manager runtime. This completes the TFIM configuration of the STS chain.

Testing and debugging the solution

There are several components in the authentication flow described in Figure 1, including:

  • The user/browser
  • The point-of-contact (WebSEAL)
  • The EAI Application
  • The TFIM runtime application

Each of these components provides debugging and tracing opportunities for problem determination. This section describes some of those that I found to be most useful during the development of this article.

Debugging at the browser

The browser itself, or a command-line browser utility like cURL (which is widely available on most Linux® distributions) is used to drive the end-user testing of the EAI servlet, and is typically the first place where indications of a problem appear. For example a 403 Forbidden message from WebSEAL, indicating that you have not allowed unauthenticated access to the EAI servlet (see Listing 4 for details of configuring an unauthenticated-allowed ACL). Other errors might also appear in the browser that originate at the trust server or at the EAI Servlet. Using the curl command-line browser to drive simple test cases allows you to check both HTTP response codes and detailed response text, which is extremely useful. An example invocation might be like that shown in Listing 8:

Listing 8. Using curl to invoke EAIServlet
[root@PestRHAS3 root]# curl -k -v https://10.1.1.111/FIM/EAISTS/EAIServlet
* About to connect() to 10.1.1.111:443
* Connected to test.ibm.com (10.1.1.111) port 443
* SSL connection using AES256-SHA
* Server certificate:
*        subject: /C=AU/CN=test.ibm.com
*        start date: 2007-08-27 02:01:11 GMT
*        expire date: 2013-04-05 02:01:11 GMT
*        common name: test.ibm.com (does not match '10.1.1.111')
*        issuer: /C=AU/CN=test.ibm.com
> GET /FIM/EAISTS/EAIServlet HTTP/1.1
User-Agent: curl/7.10.6 (i386-redhat-linux-gnu) libcurl/7.10.6 OpenSSL/0.9.7a ipv6
    zlib/1.1.4
Host: 10.1.1.111
Pragma: no-cache
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*

< HTTP/1.1 200 OK
< content-length: 378
< content-type: text/html
< date: Tue, 30 Dec 2008 05:17:11 GMT
< p3p: CP="NON CUR OTPi OUR NOR UNI"
< server: WebSEAL/6.0.0.1 (Build 060314)
< pragma: no-cache
< cache-control: no-cache
< Set-Cookie: PD-S-SESSION-ID=2_ugwTEI+91H-eV+N3GFrYlvkOo1-YIHbc0qi-xe2ACQWD0GxW;
    Path=/; Secure
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
<!-- Copyright (C) 2000 Tivoli Systems, Inc. -->
<!-- Copyright (C) 1999 IBM Corporation -->
<!-- Copyright (C) 1998 Dascom, Inc. -->
<!-- All Rights Reserved. -->
<HTML>
<HEAD>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<TITLE>Success</TITLE>
</HEAD>
<BODY>
<P>Your login was successful.
</BODY>
</HTML>
* Connection #0 left intact
* Closing connection #0

In the particular example given in Listing 8 the request was successful, and a WebSEAL cookie was set in the response. This shows that a session has been established with WebSEAL (note the response HTTP header Set-Cookie with the PD-S-SESSION-ID value.

In any case, it is highly probable that your first indication of an error will be unexpected output at the browser. This is valuable information in determining the root cause of the problem.

Debugging at WebSEAL

There are several very important components related to WebSEAL that are essential for developing and debugging a solution like the one presented in this article:

  • The EPAC CGI application is essential. When a successful authentication occurs the user can observe the contents of the user credential, including all the credential attributes. Besides indicating a successful login, it is also useful for developing authorization rules for application authorization policy. The EPAC CGI application requires that the PDAuthADK and PDWebADK packages are installed on the WebSEAL system. Further details about its installation and configuration can be found in the README that ships with the demo application at <pdwebrte_install_root>/epac_demo/README. There is also a good developerWorks tutorial on a JSP equivalent to the EPAC CGI. It can also be used to inspect the contents of the user's WebSEAL credential.
  • The WebSEAL request log (typically located at /var/pdweb/www-default/log/request.log) is a good source to check that browser requests are getting to WebSEAL. Inspecting the request.log for subsequent requests to check for an authenticated user identity and response codes can be useful in certain situations. If the EAI servlet application does not appear to be receiving requests, the WebSEAL request log is a good place to look.
  • The WebSEAL pdweb.snoop trace is extremely useful for debugging messages between WebSEAL and the EAI servlet. This can be used to check that the correct EAI headers are returned to WebSEAL from the EAI Servlet. To enable pdweb.snoop trace, use a pdadmin command like that shown in Listing 9:
    Listing 9. Enabling pdweb.snoop trace
    pdadmin> server task <server_name> trace set pdweb.snoop.jct 9
    file path=/tmp/pdweb.snoop

    After running the browser request to the EAI Servlet one time, stop and restart WebSEAL - this will in effect disable the trace and flush the trace log all at one time. The /tmp/pdweb.snoop file can then be inspected to check the traffic between WebSEAL and the EAI Servlet.

    If everything looks correct in these traces, then check the WebSEAL configuration of EAI and trigger URLs (a common area for mistakes).

Debugging at the EAI application and Tivoli Federated Identity Manager runtime

The EAI application and TFIM both run on WebSphere software and as such, debugging information can be determined using WebSphere tracing. Listing 1 shows that the demonstration servlet makes use of the standard java.util.logging logging and tracing infrastructure. The TFIM runtime also uses this same infrastructure. For the purposes of debugging calls to the TFIM trust server, the trace configuration string shown in Listing 10 is recommended.

Listing 10. Trace configuration string for the TFIM Security Token Service
*=info: com.tivoli.am.fim.trustserver.sts.modules.*=all

More information on TFIM servicability is in the TFIM online documentation here.

About the example code

The example application available in the Downloads section contains a ready-to-install EAR file that will run on a WebSphere server version compatible with the TFIM 6.2 runtime. Embedded in this file are a number of application JARs and Java source files. The Java source files are example code - distributed without warranty, and may be freely used, copied or modified. The embedded JARs might become outdated and need to be replaced, and come from the following locations.

This set of jar files is from TFIM, and ship with TFIM (starting from TFIM 6.2, Fix Pack 1) in the <fim_install_root>/examples/mapping_extension_functions directory:

  • com.tivoli.am.fim.common_6.2.0.0.jar
  • com.tivoli.am.fim.sts_6.2.0.0.jar
  • itfim-locale-msgs.jar

This set of jar files is part of the Higgins open source project (and its dependencies), and ship with TFIM starting from TFIM 6.2, Fix Pack 1 in the <fim_install_root>/adks/client/sts directory:

  • org.eclipse.higgins.configuration.api.jar
  • org.eclipse.higgins.sts.api.jar
  • org.eclipse.higgins.sts.binding.axis1x.client.jar
  • org.eclipse.higgins.sts.binding.axis1x.common.jar
  • org.eclipse.higgins.sts.binding.common.jar
  • org.eclipse.higgins.sts.client.jar
  • org.eclipse.higgins.sts.common.jar
  • axiom-api-1.2.2.jar
  • axiom-dom-1.2.2.jar
  • axiom-impl-1.2.2.jar
  • axis.jar
  • stax-api-1.0.1.jar
  • wstx-asl-3.0.0.jar

The example EAIServlet code makes use of the Higgins STS client to contact the TFIM Security Token Service. More information on the Higgins project is available here.

Variants of the solution

The model described in this article can be modified to suit a variety of scenarios. This section describes some of the scenarios that have been considered.

Leveraging WebSphere security for authentication

As one example, consider an existing WebSphere registry configuration that authenticates a username and password against an external registry that is not compatible with Tivoli Access Manager for eBusiness. The goal is to establish a WebSEAL session for this user. If the TFIM runtime is installed on this WebSphere server, the trust chain can be modified to have the first module in the chain perform a UsernameToken validate directly against the WebSphere registry (rather than the STSUU validate described above). The EAI application sends the provided username and password in a UsernameToken to the TFIM STS instead of an STSUU token. In that case, authentication is being indirectly performed by TFIM (actually WebSphere) as well.

Writing a custom STS module for authentication

Taking this one step further - If there is a custom authentication method in use and you have more than one point of contact where users need to be authenticated (for example, Web services as well as browser-based access), it might make sense to author your own STS module to do validation of the authentication data in the TFIM STS rather than to code that function into the EAI application. Then multiple authentication points can leverage the same SOA service (the TFIM STS) to have that authentication data validated, regardless of access channel. There is a detailed STS module development tutorial available that describes how to author and deploy your own STS module for TFIM.

Using TAMeB Web plug-ins instead of WebSEAL

Another variant to consider is if you want to use the TAMeB Web plug-ins rather than WebSEAL. This TAMeB component also supports EAI authentication, and the solution should apply just as well as with WebSEAL.

Using TAMeB groups and ACLs for authorization

It is also possible to use a hybrid directory solution where TAMeB groups are employed but not all the users are in the TAMeB directory. This allows authorization policy to be defined using the (much faster at runtime) TAMeB ACL policy model, rather than TAMeB authorization rules. This is preferable in very high-performance environments but comes at the expense of extra directory synchronization and management. The basic premise is that TAMeB ACLs are created and applied to WebSEAL-protected objects based on group entries. The TAMeB credential created by the TFIM runtime during EAI authentication must contain corresponding TAMeB group entries so that ACL authorization checks succeed or fail as they should. The rest of this section demonstrates how you can add a TAMeB group to a credential using the EAIServlet application and the TFIM STS.

Imagine for example that you have a number of groups in an external directory with memberships for your actual users. You create corresponding groups (matched on group name) in the TAMeB directory using the standard TAMeB administration tools and have a process that keeps the set of groups in synch with your external directory. Note this is not the group memberships, just the set of group names. Each of the TAMeB groups has its short name (which matches the name in the real directory), and an associated universally unique identifier (UUID) and registry distinguished name (DN). The DN you set when you created the group, but the UUID is created transparently for you by TAMeB. First you need to know the UUID and DN for your group. The example in Listing 11 demonstrates how to determine that information. The example shows two different LDAP searches - the first if you are using the "minimal" LDAP schema for TAMeB, and the second is if you are using the legacy traditional LDAP schema for TAMeB, where TAMeB group information is contained as a child of the actual group entry:

Listing 11. Determining a TAMeB group UUID
#### EXAMPLE OF DETERMINING TAMeB GROUP UUID IF USING MINIMAL TAMeB LDAP SCHEMA #####

pdadmin sec_master> group show testgroup
Group ID: testgroup
LDAP DN: cn=testgroup,c=us
Description:
LDAP CN: test
Is SecGroup: Yes
pdadmin sec_master> quit

# ldapsearch -h localhost -p 389 -D cn=root -w passw0rd -b "secauthority=default" -s sub \
    "(&(objectclass=*)(secDN=cn=testgroup,c=us))"  secUUID
cn=testgroup,cn=Groups,secAuthority=Default
secuuid=35e2c214-d863-11dd-aeb2-000d6049840e




#### EXAMPLE OF DETERMINING TAMeB GROUP UUID IF USING LEGACY TAMeB LDAP SCHEMA ####

pdadmin sec_master> group show testgroup
Group ID: testgroup
LDAP DN: cn=testgroup,c=us
Description:
LDAP CN: test
Is SecGroup: Yes
pdadmin sec_master> quit

# ldapsearch -h localhost -p 389 -D cn=root -w passw0rd -b cn=testgroup,c=us -s one \
    "(objectclass=*)" secUUID
secAuthority=Default,cn=testgroup,c=us
secUUID=35e2c214-d863-11dd-aeb2-000d6049840e

Now for each TAMeB group you have:

  • The group short name (which matches the group name in your external directory) - for example, testgroup
  • The group DN - for example, cn=testgroup,c=us
  • The group UUID - for example, 35e2c214-d863-11dd-aeb2-000d6049840e

During authentication, you determine from the external directory which groups the user is a member of. You can then update the STSUniversalUser to contain that group information using code similar to that shown in Listing 12:

Listing 12. Adding a TAMeB group to the STSUniversalUser
...
import com.tivoli.am.fim.trustserver.sts.STSUniversalUser;
import com.tivoli.am.fim.trustserver.sts.uuser.Attribute;
import com.tivoli.am.fim.trustserver.sts.uuser.Group;
...

  /**
   * Adding a TAMeB group to the STSUniversalUser based on the short name, DN, and UUID
   */
  void addTAMGroup(STSUniversalUser stsuu, String groupShortName,
    String groupDN, String groupUUID) {
    final String TAM_TYPE = "urn:ibm:names:ITFIM:5.1:accessmanager";

    Attribute[] attrs = new Attribute[] {
     new Attribute("uuid", TAM_TYPE, new String[] { groupUUID }),
     new Attribute("registryid", TAM_TYPE, new String[] { groupDN }) };

    Group g = new Group(groupShortName, TAM_TYPE, attrs);

    stsuu.addGroup(g);
}

Following our example, adding the testgroup is done in the EAIServlet when building the STSUU, as shown in Listing 13:

Listing 13. Adding testgroup to the STSUniversalUser
    addTAMGroup(
        stsuu,
        "testgroup",
        "cn=testgroup,c=us",
        "35e2c214-d863-11dd-aeb2-000d6049840e");

Finally there is one more important update that needs to be made to the TFIM runtime. By default the TAMeB credential STS module does not allow the dynamic addition of groups. This is a historical property of the TAMeB credential module, but can be changed with configuration. To allow the TAMeB credential STS module to add groups to the credential, use the TFIM console and navigate to Domain Management -> Runtime Node Management, then click Runtime Custom Properties, as shown in Figure 13:

Figure 13. Setting runtime custom properties
Setting runtime custom properties

Click Create to create a new attribute, then change the new attribute's name to: ivcred.allow.groupUpdate, with a value of true, as shown in Figure 14 (don't be concerned if the list of other properties shown in the figure does not match your configuration):

Figure 14. Setting ivcred.allow.groupUpdate
Setting ivcred.allow.groupUpdate

You can now use the servlet to create a TAMeB credential with the TAMeB group in it, like that shown in Figure 15:

Figure 15. TAMeB credential with a dynamically added group
TAMeB credential with a dynamically added group

A TAMeB ACL can now be used with the testgroup entry, and this user would be permitted access. Note that the TAMeB authorization runtime matches the UUID to do its actual authorization checks, so the UUID is a critical element of correctly building a TAMeB group from TFIM.

Other important considerations

Whenever you use an EAI authentication solution with WebSEAL, rather than the native TAMeB user registry support, there are a variety of capabilities that you must manually set for yourself in the EAI application. These considerations are significant if the means of authentication is actually a username and password, and include things such as:

  • Password Change and Recovery
  • Password Policy including min and max length, re-use, strength, and expiration
  • User account lifecycle management including the provisioning, enabling, disabling and deletion of user accounts

Any solution leveraging EAI (including one such as this where the users don't actually reside in the TAMeB user registry) must consider and implement auxilary account and authentication support functions such as those mentioned here.


Download

DescriptionNameSize
Sample EAI Servlet using STS clienteaistsear.ear8MB

Resources

Comments

developerWorks: Sign in

Required fields are indicated with an asterisk (*).


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Information in your profile (your name, country/region, and company name) is displayed to the public and will accompany any content you post, unless you opt to hide your company name. You may update your IBM account at any time.

All information submitted is secure.

Choose your display name



The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

Required fields are indicated with an asterisk (*).

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


All information submitted is secure.

Dig deeper into Security on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Security, Tivoli (service management), Tivoli
ArticleID=365372
ArticleTitle=Using Tivoli Access Manager for eBusiness WebSEAL without a user registry
publish-date=02032009