User-Centric Identity with Tivoli Federated Identity Manager, Part 1: Replace Password Authentication on your Web site with an Information Card or OpenID

Using User-Centric Identity technologies like Information Cards and OpenID as an alternate to Password Authentication with Tivoli Federated Identity Manager

Do you like remembering and updating passwords? Most of us do not. A lot of corporate dollars are spent on customer service for password resets. This article presents a way for users to establish alternate means of authenticating to IBM® WebSphere® or IBM Tivoli® Access Manager environments using Information Cards and OpenID's. The flow is simple - the user first authenticates to the site using an existing authentication mechanism (which may be username/password or some other means), then "links" a user-centric credential (i.e., an information card or openid) to their account. Thereafter the Information Card or OpenID can be used as the primary means of authentication. This is quite convenient for customers as they become in charge of their own authenticated identity provider.

Share:

Shane B. Weeden, Senior Software Engineer, IBM Tivoli

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.



06 October 2008

Pre-requisite knowledge

This is an advanced article, and is targeted at readers who:

  • Have a basic familiarity with user-centric identity technologies like Information Cards and OpenID
  • Are extremely competent in the deployment and configuration of Tivoli Federated Identity Manager 6.2
  • Are comfortable reading and understanding XSLT mapping rules with TFIM, as the article will present custom mapping rules which leverage TFIM-provided API's for reading and storing aliases

The article will help instruct you to perform TFIM configuration tasks with high-level directions, such as creating federations, updating mapping rules, etc. If this is not familiar terminology, you may need to seek basic training in Tivoli Federated Identity Manager before trying to implement the techniques described in this article.

Risks and requirements for adoption

The solution allows for the replacement of password authentication (or any other authentication method) with authentication via a credential issued by an identity provider selected by the user. The system can always enforce some restrictions on the set of identity providers, however allowing the user to select their own, or in the case of information cards using a self-issued card, provides for the greatest convenience and flexibility for users. This flexibility also has risks to the user's account data as the security of authentication to any user-centric enabled site becomes only as secure as the means of authentication to the issuer of the user-centric credential. Provided the business can accept this risk, or transfer the risk to the consumer (which is a large "if"), and the consumer is careful in their selection of an identity provider (particularly for OpenID), the model provides a very convenient way for consumers to replace their password-based authentications with a federated single sign-on using an identity provider of their choice.

The solution as presented uses Tivoli Federated Identity Manager 6.2 for processing user-centric credentials. Consequently the environments to which the solution applies are restricted to those authentication environments integrated with TFIM. Out-of-the-box this includes Tivoli Access Manager and environments supporting LTPA authentication such as WebSphere and Domino, plus other environments which have TFIM integration such as ASP.NET.

Solutions Overview

The solution described by this article makes use of Tivoli Federated Identity Manager 6.2 support for Information Card and OpenID technology, although the fundamental design principals are not product-specific. At a high level, Figure 1 presents user-interaction diagram which describes bootstrapping the user-centric authentication process:

Figure 1. Linking a user-centric authentication credential to an existing account
Linking Overview

When an unauthenticated user later visits the site and is prompted for login, they may present their user-centric credential as a means of authentication. The unique, security-related alias associated with that credential is used to "lookup" the linked user id and log the user in.

There is some processing logic to be applied when a user presents a user-centric credential, and that logic is best explained with the following flowchart which would apply during either the linking process, or an attempt to authenticate after linking.

Figure 2. Processing a user-centric credential for authentication or linking to an existing account
Linking Overview

Note that in the above diagram while self-registration is outside the scope of this article, a follow-up article will cover expanding this scenario to include self-registration.

The user-centric credential alias

From the flowchart in Figure 2 you can see that a key element of linking of a user-centric credential to a user's account is the notion of a unique identifier (aka alias) which can be derived from the user-centric credential. One key concept with user-centric credentials is that the relying-party site (i.e. our website which is receiving these credentials) doesn't need to trust where the credential comes from, only that there is only one user who can successfully present the credential in a secure way, and that this same user can re-present the same credential in the future. This differs from a password only in that the user interacts with a 3rd-party identity provider to authenticate, and the relying-party can securely determine that the user has done this. There is no need for a "trust relationship" between the relying-party and the issuer of the user-centric credential. This is quite a different model to traditional federated single sign-on protocols like Liberty and SAML which require out-of-band sharing of secret key and endpoint information, and allows for a more distributed, rapid-adoption deployment of cross-web-domain single sign-on technology.

In this article we demonstrate two types of user-centric credentials - Information Card and OpenID. In each case however it's necessary to establish a "unique identifier" which can be used as the alias to link to the user's account. The choice for the unique alias is shown in the following table:

Table 1. Unique alias values for user-centric credentials
User-Centric TechnologyAlias Value
Information CardThe alias to be used will be the uniqueid attribute provided by Tivoli Federated Identity Manager after an Information Card login has been processed. This uniqueid is a cryptographic hash of the Private Personal Identifier (PPID) of the card with the public key of the issuer who presented it. The uniqueid attribute is specifically designed by TFIM for this purpose.
OpenIDThe alias to be used will be the claimed identifier that the relying party discovers from the user-supplied identity that end-user types into the OpenID login form.

The mapping rule

For the purposes of this article we are going to further refine the flowchart described in Figure 2 to restrict a user to at most one alias at a time. This simplifies the mapping rule a little, and allows for easier debugging and tracking of which users own which aliases.

This article will provide working examples of a mapping rule that implements linking of an alias to a user in both XSLT and Java. These mapping rules will be functionally identical, the only difference will be the implementation strategy (and how they are configured into the STS trust chain). The article will describe the XSLT mapping rule implementation in detail, and the Java™ mapping rule implementation will be provided in the downloads section for interested developers to use or modify.

Extension functions

TFIM 6.2 introduces several extension functions for customers to use in either XSLT mapping rules, or in custom Java plug-ins that might be written for mapping or token manipulation. In the mapping rule we will make use of the following extension functions:

  • lookupUserFromAlias: to determine if a presented alias is currently linked to a known user account
  • removeAliasForUser: to remove an alias from a user account. This is used in two cases:
    • To remove an alias from an existing user if a new user is now adopting that alias
    • To remove an alias from an existing user if that user is adopting a new alias
  • lookupAliasesForUserAsDelimitedString: to determine if a user account has an existing alias attached to it. This is needed because there is no "replaceAlias" function, and to enforce the at-most-one-alias-per-user policy we need to check if a user has any existing alias before adding a new alias for that user.
  • addAliasForUser: to add an alias to an existing user account
  • throwSTSException: if an error case is detected (including an unauthenticated user presenting an alias that is not linked to a known user account)

XSLT mapping

Listing 1 presents the entire XSLT mapping rule, with full error handling, used for this demonstration. This implements the logic shown in Figure 2 with the addition of the policy that a user may have at most one alias at a time.

Listing 1. XSLT mapping rule for user-centric aliases
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:stsuuser="urn:ibm:names:ITFIM:1.0:stsuuser"
  xmlns:fimqs="urn:ibm:names:ITFIM:queryservice"
  xmlns:fimsaml="urn:ibm:names:ITFIM:saml"
  xmlns:fimopenid="urn:ibm:names:ITFIM:openid"
  xmlns:mapping-ext="com.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils"
  extension-element-prefixes="mapping-ext" version="1.0">

  <xsl:strip-space elements="*" />
  <xsl:output method="xml" version="1.0" encoding="utf-8"
    indent="yes" />

  <!-- 
  Initially we start with a copy of the document. 
  -->
  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()" />
    </xsl:copy>
  </xsl:template>

	
  <!--  
  Name of the federation context we will 'alias' to. Note that in this demo,
  we have ONE federation name shared regardless of whether you are allowing 
  users to link OpenID's, InfoCards or both. The mapping rule is implemented
  so that a user can have at MOST ONE alias, regardless of what type of 
  alias that is. To say that another way, this rule enforces that only one 
  OpenID OR one InfoCard can be linked to an account at the time. It is
  possible to write the rule for multiple aliases, and for different 
  federation names for OpenID vs InfoCard, however for the purposes of this 
  demo we	have chosen the single-alias-at-a-time approach described above.
  -->
  <xsl:variable name="fedCtx" select="'myfedctx'" />
	

  <!-- 
  Use either 'OpenID' or 'InfoCard' as the fedType, and the rest should work 
  from that. We make a smart determination of the fed type from the claims 
  type found in the STSUU.
  -->
  <xsl:variable name="fedType">
    <xsl:choose>
      <xsl:when test="//fimopenid:OpenIDClaims">OpenID</xsl:when>
      <xsl:otherwise>InfoCard</xsl:otherwise>
    </xsl:choose>
  </xsl:variable>


  <!-- 
  The alias to be stored in the alias service. For OpenID this is the
  claimed identifier. For InfoCard it's the uniqueid attribute supplied
  by TFIM after validation of an InfoCard token.
  -->
  <xsl:variable name="alias">
    <xsl:choose>
      <xsl:when test="$fedType = 'OpenID'">
        <!--  using OpenID - alias is the claimed identifier -->
        <xsl:value-of
          select="//stsuuser:Principal/stsuuser:Attribute[@name='name']/stsuuser:Value" />
      </xsl:when>
      <xsl:otherwise>
        <!--  using InfoCard - alias is the uniqueid -->
        <xsl:value-of
         select=
         "//stsuuser:AttributeList/stsuuser:Attribute[@name='uniqueid']/stsuuser:Value" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>


  <!--  Name of user the alias is currently linked to -->
  <xsl:variable name="linkedUser" 
    select="mapping-ext:lookupUserFromAlias($fedCtx, $alias)" />


  <!--  Name of the currently logged-in user -->
  <xsl:variable name="authenticatedUser">
    <xsl:choose>
      <xsl:when test="$fedType = 'OpenID'">
        <!--  using OpenID -->
        <xsl:value-of
          select="//fimopenid:OpenIDClaims/fimopenid:PrincipalName" />
      </xsl:when>
      <xsl:otherwise>
        <!--  using InfoCard - alias is the uniqueid -->
        <xsl:value-of
          select="//fimsaml:SAMLClaims/fimsaml:PrincipalName" />
      </xsl:otherwise>
    </xsl:choose>
  </xsl:variable>

  <!-- 
  This template replaces the entire Principal, applying the alias processing
  rules to either link the alias to an existing account, or login as a user
  who is linked with the provided alias.
  -->
  <xsl:template match="//stsuuser:Principal">
    <stsuuser:Principal>
      <stsuuser:Attribute type="urn:ibm:names:ITFIM:5.1:accessmanager" name="name">
        <stsuuser:Value>
          <xsl:choose>
            <!-- Determine if we have an existing user linked to the alias -->
            <xsl:when test="string-length($linkedUser) > 0">
              <xsl:choose>
                <xsl:when test="string-length($authenticatedUser) > 0">
                  <!--  
                  We will always stay logged in as the authenticatedUser in
                  this case, the only thing we need to determine is if
                  the linked user is different from the authenticatedUser.
                  If they are different, we need to unlink from the existing
                  linked user, and link to the authenticated user. We also
                  need to remove any existing alias from the authenticated
                  user to ensure the authenticated user has at most one
                  alias at a time (that's what this demo's policy is).
                  -->
                  <xsl:if test="not($linkedUser = $authenticatedUser)">

                    <!-- Unlink alias from existing linked user -->
                    <xsl:variable name="unlinkResult" 
                      select="mapping-ext:removeAliasForUser(
                        $fedCtx, $linkedUser, $alias)" />
                    <xsl:if test="not($unlinkResult = 'true')">
                      <xsl:variable name="error" 
                        select="concat(
                        'Failed to unlink alias: ', $alias, 
                        ' from existing user: ', $linkedUser)" />
                      <xsl:value-of 
                        select="mapping-ext:throwSTSException($error)" />
                    </xsl:if>

                    <!-- 
                    Determine if currently authenticated user has
                    an alias, and remove it if they do.
                    -->
                    <xsl:variable name="existingAlias" 
                      select="mapping-ext:lookupAliasesForUserAsDelimitedString(
                        $fedCtx, $authenticatedUser, ',')" />
                    <xsl:if test="string-length($existingAlias) > 0">
                      <!-- 
                      this assumes there is at most one alias, and the delimiter 
                      is therefore unused 
                      -->
                      <xsl:variable name="unlinkResult" 
                        select="mapping-ext:removeAliasForUser(
                          $fedCtx, $authenticatedUser, $existingAlias)" />
                      <xsl:if test="not($unlinkResult = 'true')">
                        <xsl:variable name="error" 
                          select="concat(
                            'Failed to unlink existing alias: ', $existingAlias, 
                            ' for authenticatedUser: ', $authenticatedUser)" />
                        <xsl:value-of 
                          select="mapping-ext:throwSTSException($error)" />
                      </xsl:if>
                    </xsl:if>

                    <!-- Link alias to authenticated user. -->
                    <xsl:variable name="linkResult" 
                      select="mapping-ext:addAliasForUser(
                        $fedCtx, $authenticatedUser, $alias)" />
                    <xsl:if test="not($linkResult = 'true')">
                      <xsl:variable name="error" 
                        select="concat(
                          'Failed to link alias: ', $alias, 
                          ' to user: ', $authenticatedUser)" />
                      <xsl:value-of 
                        select="mapping-ext:throwSTSException($error)" />
                    </xsl:if>
                  </xsl:if>
 
                  <!-- Stay logged in as the authenticatedUser -->
                  <xsl:value-of select="$authenticatedUser" />
                </xsl:when>
                <xsl:otherwise>
                  <!-- 
                  No-one logged in, and we have a linked user. 
                  Login as that linked user. This is the normal
                  authentication case when someone has already 
                  linked an alias.
                  -->
                 <xsl:value-of select="$linkedUser" />
                </xsl:otherwise>
              </xsl:choose>
            </xsl:when>
            <xsl:otherwise>
              <!-- No existing linked user - is someone logged in? -->
              <xsl:choose>
                <xsl:when test="string-length($authenticatedUser) > 0">
                  <!-- 
                  Determine if the authenticated user has any 
                  existing alias and remove it if they do. This
                  is part of ensuring at most one alias per user.
                  -->
                  <xsl:variable name="existingAlias" 
                    select="mapping-ext:lookupAliasesForUserAsDelimitedString(
                      $fedCtx, $authenticatedUser, ',')" />
                  <xsl:if test="string-length($existingAlias) > 0">
                    <!-- 
                    this assumes there is at most one alias, and the delimiter 
                    is therefore unused 
                    -->
                    <xsl:variable name="unlinkResult" 
                      select="mapping-ext:removeAliasForUser(
                      $fedCtx, $authenticatedUser, $existingAlias)" />
                    <xsl:if test="not($unlinkResult = 'true')">
                      <xsl:variable name="error" 
                        select="concat(
                        'Failed to unlink existing alias: ', $existingAlias, 
                        ' for authenticatedUser: ', $authenticatedUser)" />
                      <xsl:value-of 
                        select="mapping-ext:throwSTSException($error)" />
                    </xsl:if>
                  </xsl:if>

                  <!-- 
                  Link the current alias to the authenticatedUser
                  -->
                  <xsl:variable name="linkResult" 
                    select="mapping-ext:addAliasForUser(
                    $fedCtx, $authenticatedUser, $alias)" />
                  <xsl:if test="not($linkResult = 'true')">
                    <xsl:variable name="error" 
                      select="concat(
                      'Failed to link alias: ', $alias, 
                      ' to authenticatedUser: ', $authenticatedUser)" />
                    <xsl:value-of 
                      select="mapping-ext:throwSTSException($error)" />
                  </xsl:if>

                  <!-- Stay logged in as the authenticatedUser -->
                  <xsl:value-of select="$authenticatedUser" />
                </xsl:when>
                <xsl:otherwise>
                  <!-- 
                  No-one logged in, and no linked user. 
                  This is an error for our demo, but also an
                  opportunity to do self-registration if you are 
                  so inclined.
                  -->
                  <xsl:variable name="error" 
                    select="concat(
                    'Aborting login because alias: ', $alias, 
                    ' is not linked to any user account.')" />
                  <xsl:value-of select="mapping-ext:throwSTSException($error)"/>
                </xsl:otherwise>
              </xsl:choose>
            </xsl:otherwise>
          </xsl:choose>
        </stsuuser:Value>
      </stsuuser:Attribute>
    </stsuuser:Principal>
  </xsl:template>

</xsl:stylesheet>

Java mapping

Please see the Downloads section where you can download a TFIM custom Java mapping module (including source) which implements exactly the same logic as the above XSLT mapping rule. The downloadable JAR is an OSGi bundle that can be inserted directly into your plug-ins directory on your FIM installation (<TFIM_install_root>/plugins) and deployed to the TFIM runtime. You can also import the JAR as a project into Rational Application Developer or Eclipse when configured for a TFIM plug-in development environment. For more information on developing OSGi plug-ins for TFIM 6.2 and establishing a TFIM plug-in development environment, please see the developerWorks® tutorial I have co-authored on this topic.
After deploying the bundle to your runtime, follow these high-level steps to use it in your federation:developerWorks

  • Create an instance of the mapping module using the TFIM Console under Configure Trust Service -> Module Instances -> Create. You should see a module type with the class name: com.tivoli.am.fim.demo.linkingmap.LinkingMap
  • Navigate to your federation's properties page, scroll to the bottom, and select Change Identity Mapping Module Instance... then select your new module instance and submit the changes
  • Reload configurations for the TFIM Runtime, and you should be ready to test.

Deploying the solution

This section discusses the various activities involved in deploying a solution that utilizes a linked OpenID or Information Card as an alternate means of authentication to your site.

Configuring the alias service

The mapping module makes use of extension functions which rely on the TFIM alias service, so be sure to configure the alias service for your domain using the TFIM Console: Domain Management -> Alias Service Settings. If you are using the XSLT mapping rule and the JDBC alias service you will need fixpack 1 or later for TFIM 6.2 as there is a known issue calling the IDMappingExtUtils functions with the JDBC alias service from XSLT. If using the LDAP alias service, or the custom Java mapping module, fixpack 1 or later is not a requirement.

Configuring your Federation(s)

Create your OpenID and/or Information Card relying party federation using the TFIM console, and use the example mapping rule shown in Listing 1 as the mapping rule for the configuration, or alternatively use an instance of the Java mapping module available in the Downloads section.

Make sure you also configure the TAM policy if you are using a TAM point of contact.

Web site and TFIM page customizations

You will need to modify your site for the following purposes:

  • Provide a page for authenticated users to link an OpenID and/or Information Card to their account for future authentication. Ideally this page should also show any currently linked alias.
  • Modify the login page for the site to allow users who have established an alias to login via their OpenID and/or Information Card.


For testing purposes, you can just switch to the TFIM Install/Verification Test Application (itfim-ivtapp.ear) to perform OpenID or Information Card authentications when necessary, however this does not provide the user experience you need for end-users.

As part of meeting these requirements we will build an "enablement" J2EE™ application using JSPs which is supplemental to our environment. This application is available as a download in the Downloads section called linkingenablement.zip. Unzip this file to find linkingenablement.ear which can be installed on your application server. If you choose to use this application, install it on a WebSphere application server (this can be the same server as the TFIM runtime) and junction behind WebSEAL if using a TAM point of contact.

The first page we will build is a welcome page for authenticated users which will display a menu inviting them to view their existing alias, or link an OpenID or Information Card to their account. As this is a page for authenticated users, it should be protected with a J2EE security constraint or TAM ACL depending on your point-of-contact settings. The welcome page looks like that depicted in Figure 3:

Figure 3. Welcome page for authenticated users
Welcome Page

Alias Delegate Information

TFIM provides a built-in delegate URL for displaying and allowing a user to remove aliases linked in the alias service. This URL is at the TFIM endpoint /sps/alias. The View your alias link in our welcome page points to this alias delegate. The alias delegate takes a partner parameter as an argument (via GET or POST). This partner parameter corresponds to the federation context used when storing the alias, and the page will display the aliases for that partner along with links to remove the aliases. For the example environment, which uses TAM as a point-of-contact, the full URL to the alias service looks like:

  • https://www.ibmidentitydemo.com/FIM/sps/alias?partner=myfedctx


The page is customizable in TFIM, and replacement macros control the variable portions of the page. The standard page supports multiple aliases per partner, although in our demonstration we have coded the mapping rule to restrict a user to one alias at a time. The default page template for the alias delegate can be found at <FIM_install_root>/pages/C/alias/alias.html, and is show in Listing 2:

Listing 2. Default alias delegate page
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>Alias Manager</title>
  </head>
  <body>
    <p />
    Associated aliases for @USERNAME@:<br />
    <table border="1">
        <tr><td>Partner</td><td>Alias</td><td>Action</td></tr>
      [RPT aliasEntry]
        <tr>
            <td>@PARTNER_ID@</td>
            <td>@ALIAS_ID@</td>
            <td>
<a href="@ALIASMANAGER_URL@?action=remove&alias=@URLALIAS@&username=@USERNAME@">Remove</a>
            </td>
        </tr>
      [ERPT aliasEntry]
    </table>
  </body>
</html>

You can see special tags [RPT aliasEntry] and [ERPT aliasEntry] in the page. These tags delimit a "repeatable block", which will be duplicated once for each alias for a given partner id. In this way if a user had more than one alias associated with a given partner id, multiple rows would be shown in the table. In our example mapping rules, we should only ever see one row. The various replacement macros available are described in Table 1:

Table 2. Replacement macros for alias.html
MacroDescription
@USERNAME@This is replaced with the username of the currently authenticated user. It can appear either inside or outside the [RPT aliasEntry] / [ERPT aliasEntry] block.
@ALIASMANAGER_URL@This is replaced with the URL of the alias endpoint. It can appear either inside or outside the [RPT aliasEntry] / [ERPT aliasEntry] block and is used to generate links for removing aliases.
@PARTNER_ID@This macro belongs inside a [RPT aliasEntry] / [ERPT aliasEntry] block, and will be replaced with a federation context id for one of the aliases associated with the user.
@ALIAS_ID@This macro belongs inside a [RPT aliasEntry] / [ERPT aliasEntry] block, and will be replaced with one of the aliases associated with the user.
@URLALIAS@This macro belongs inside a [RPT aliasEntry] / [ERPT aliasEntry] block, and will be replaced with the URL-encoded version of the string "@PARTNER_ID%@ALIAS_ID@" for the alias being displayed. This value is used in the generation of URL's for removing aliases.

Figure 4 shows a screenshot of an example alias page where the user has linked an Information Card to their account:

Figure 4. Example alias page
Example Alias Page



Linking Source for Information Card and OpenID

The remaining options in the welcome.jsp show a login link for an information card and a similar login link for an OpenID.


The JSP source for prompting for an information card is shown in Listing 3:

Listing 3. Prompting for an information card
<form method="post" action="<%=conf.getInfocardLoginDelegate()%>">
  <object name="xmlToken" id="oCard" type="application/x-informationCard">
    <param value="urn:oasis:names:tc:SAML:1.0:assertion" name="tokenType">
    <param 
   value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/privatepersonalidentifier"
   name="requiredClaims">
  </object>
  <input name="TARGET" type="hidden" value="<%=conf.getLinkLandingPage()%>">
  <img height="16" width="23" src="infocard_23x16.png">&nbsp;&nbsp;
  <input value="[Link an Information Card]" class="submitLink" type="submit">
</form>


The JSP source for prompting for an OpenID is shown in Listing 4:

Listing 4. Prompting for an OpenID
<form method="post" action="<%=conf.getOpenIDLoginDelegate()%>">
<input value="checkid_setup" name="openid.mode" type="hidden">
<input name="TARGET" type="hidden" value="<%=conf.getLinkLandingPage()%>">
<input name="openid_identifier" class="openid" type="text">&nbsp;&nbsp;
<input value="Link an OpenID" type="submit">
</form>



Configuration of the Enablement Application

The linkingenablement.ear application contains an embedded configuration file called linkingenablement.properties that you can manually edit after the application is deployed. It has self-describing properties, as shown in Listing 5:

Listing 5. linkingenablement.properties
# The alias delegate on the TFIM runtime

aliasDelegate=https://www.ibmidentitydemo.com/FIM/sps/alias

# The federation context id used in your mapping rule

fedContext=myfedctx

# The login delegate URL for your infocard login delegate.

# Comment this out if you don't have an information card endpoint

infocardLoginDelegate=https://www.ibmidentitydemo.com/FIM/sps/infocardsp/infocard/login

# The login delegate URL for your infocard login delegate.

# Comment this out if you don't have an OpenID endpoint

openidLoginDelegate=https://www.ibmidentitydemo.com/FIM/sps/openidsp/openid/login

# A page to land on after either an information card or openid linking operation

linkLandingPage=https://www.ibmidentitydemo.com/FIM/LinkingEnablement/linklanding.jsp



Update your login page

The final step in this customization is to modify your login page (e.g., TAM login page, or the formlogin.html if you are using WebSphere for point of contact. The login form should be modified to contain an Information Card login prompt (similar to that shown in OpenID login prompt (similar to that shown in include different required or optional claims or sreg extension attributes in your login form (depending on application requirements). The linking operation doesn't require any special claims other than the PPID for an information card, and as such the templates shown in the listings above don't prompt for them. An example of what your new login page might look like is shown in Figure 5:

Figure 5. Example login page
Example Login Page

You will find a copy of the WebSEAL login.html used to generate the above page embedded as part of the linkingenablement.ear application.

Testing the solution

To test the solution you should at first install and use the TFIM IVT Application (itfim-ivtapp.ear) that ships with the TFIM installation. This is a very valuable application for displaying and invoking your federations.

When debugging the mapping rules, use the WebSphere tracing facility. To enable this, use the WebSphere console and navigate to:
Troubleshooting -> Logs and Trace -> server1 -> Change log level details.

Add the trace string: com.tivoli.am.fim.trustserver.sts.utilities.IDMappingExtUtils=all

If you are using the Java mapping rule, also add the trace string: com.tivoli.am.fim.demo.*=all

Test a variety of conditions, including:

  • Start unauthenticated, and login using an unlinked alias (this should be an error case and exception text thrown in the mapping rule should appear on the error screen). Note that you could launch a self-registration process as a result of this error, or cater for self-registration directly in the mapping rule. A follow-on article will present an extended solution for doing this. An example of the error page generated for this test case by the current mapping rule is shown in Figure 6:
    Figure 6. Error page displayed when an unauthenticated user presents an unlinked alias:
    Unlinked Alias Error
  • Authenticate using a username and password, then link an information card (or openid) and verify that an alias is established by looking at the alias page. You should be able to see a linked alias like that shown in Figure 4.
  • After the previous test, authenticate as a DIFFERENT user, but then link the same information card (or openid). Verify that the alias is established for the current user, and removed for the previous user.
  • Verify that you can authenticate from the main login page using an alias that has been linked to a user account.
  • Verify that an alias can be manually removed via the alias page, and that you can no longer login using that alias after it is removed.
  • Verify that different user accounts can establish unique aliases and that each alias maps correctly back to the user account it was linked against.

Downloads

DescriptionNameSize
User-Centric XSLT Mapping Moduleuser_centric_linking.xsl12KB
User-Centric Custom Java Mapping Modulecom.tivoli.am.fim.demo.linkingmap_1.0.0.jar12KB
Enablement Pageslinkingenablement.zip14KB

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 Tivoli (service management) on developerWorks


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Tivoli (service management), Security, Tivoli
ArticleID=322675
ArticleTitle=User-Centric Identity with Tivoli Federated Identity Manager, Part 1: Replace Password Authentication on your Web site with an Information Card or OpenID
publish-date=10062008