User Centric Identity with Tivoli Federated Identity Manager, Part 2: Self registration and account recovery using information cards and OpenID

Attracting users to register at your retail Web site has always been a challenge. Not only do you need to have a fantastic service to offer, you also need to make the on-boarding process as simple and convenient as possible. Traditional federation technologies like Liberty and SAML allowed companies to collaborate with tightly-coupled user bases by establishing 1:1 or many:few relationships; however, that model does not scale to the true retail space. User Centric Identity management technologies like OpenID and Information Cards allow people to manage their own identity attributes at distributed "Identity Providers" (including self-issued Information Cards). This article will demonstrate how to implement self-registration using an Information Card or OpenID (with the simple registration extension - SREG). Automated recovery of an account is also implemented, such as when the user centric credential with which it was registered is lost. Sample code is provided to rapidly enable these capabilities with IBM® Tivoli® Federated Identity Manager 6.2.

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.


developerWorks Professional author
        level

15 October 2008

Introduction

User centric deployment considerations

User Centric Identity (UCI) has many definitions. A simple description is that UCI is terminology describing how a user manages, maintains and submits to interested parties a set of personal identity attributes. Ideally the user does this in a consistent manner regardless of which site they visit. The user should be able to maintain control over which attributes are shared with different Web sites and applications. UCI protocols should be secure, open and interoperable. The Information Card and OpenID specifications have emerged as two prevalent UCI protocols and many sites today support one or both of these for authentication and attribute sharing.

There are some barriers to adoption though. Consumers may not quickly relate to the concept of an OpenID identity. Even technical users comfortable with OpenID may be reluctant to store actual identity information at a 3rd-party site. Information Cards rely on the deployment of an identity selector and a browser that supports that selector. At the time of writing that rollout is in its infancy.

That said, User Centric Identity management is a fast-growing technology and several open-source efforts have made it very cheap to deploy for non-commercial operations. There are significant benefits to both consumers and Web site managers for using these capabilities, and it is hoped that this article assists IBM customers with deployment of their own user-centric solutions with the Tivoli security suite.

Pre-requisite Knowledge

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

  • Have already read, and are familiar with the developerWorks® article on Replace Password Authentication on your Web site with an Information Card or OpenID
  • Have a basic familiarity with user-centric identity technologies like Information Cards and OpenID
  • Are competent in the deployment and configuration of Tivoli Federated Identity Manager 6.2
  • Are comfortable reading and understanding Java code and in particular Java mapping rules with TFIM, as the article will present a custom mapping rules which leverage TFIM-provided API's for reading and storing aliases

The article will instruct you to perform TFIM configuration tasks with high-level directions, such as creating federations, updating mapping rules, etc. Familiarity with these concepts in TFIM 6.2 is a requirement for implementing the techniques described in this article.

Solutions overview

The solution described by this article makes use of Tivoli Federated Identity Manager 6.2 support for Information Card and OpenID technology. The solution is a direct extension (and complete superset) of the account-linking scenario presented in my previous article on Replace Password Authentication on your Web site with an Information Card or OpenID. In the previous article TFIM was configured to permit a user to link an Information Card or OpenID to their pre-existing account, enabling their account for authentication with that credential during subsequent logins. When first linking the user-centric credential to an account, the user had to be authenticated using an existing login method such as a password. If an unauthenticated user presented a user-centric identity alias which was not linked to an existing user account, an error was displayed indicating the alias was unknown. In this article we take that error condition away, and change it to the starting point for a self-registration scenario.

An interesting observation about user-centric identity technologies is that the relying-party Web site receiving information from a user-centric identity provider does not have a pre-existing trust relationship established with the identity provider. This means that the relying-party should not just take the information it receives as fact, but should validate important pieces of information received as part of a user-centric identity token. The relying-party should be able to safely assume that the user or entity that presents a user-centric identity token should be the only user or entity that can present that same token in the future. Recall that a user-centric identity is uniquely identified in these TFIM scenarios by an alias - in our case either:

  • The claimed identifier for an OpenID
  • The TFIM-generated uniqueid for an Information Card

In addition to the alias which uniquely identifies the token, the relying party can request attribute information from the user. Both information cards and OpenID's support the notion of user's attributes. For information cards, attributes are identified as claims. For OpenID's TFIM may be used to request attributes using the Simple Registration Extension 1.0 (SREG).

To implement self-registration, the process requires an email address be supplied as an attribute during user-centric authentication. The email address becomes the user's account name in the user registry. When an unauthenticated user first presents a user-centric identity that is not linked to an existing account, the system creates a temporary, disabled account for the user (based on the email address). The system then creates a nonce (big random number), and stores the nonce and the alias of the user-centric identity token in the temporary account. Finally an email is sent to the user (based on their provided email address) with an account confirmation URL that includes the nonce. Notification is given to the user on the browser than an email has been sent. The user receives the email, clicks on the account confirmation link and re-authenticates using the same user-centric identity token that they started the process with. In this way the system can confirm that the user who has presented the user-centric identity token has access to the email address they have presented during authentication. If the account confirmation is successful, the account is fully enabled, linked to the alias associated with the user-centric identity, and the user is now registered to the system.

Many variants of this process are possible. For example if you suspect or require that user's check for their email relatively quickly and perform the second phase of the self-registration process (accessing the account-confirmation link), then it is not even necessary to create a temporary account in the user registry - that transient account information could be stored in a short-lived (e.g., 30 minute) memory cache.

A similar process to that described above for self-registration (using email verification) is also used to recover an account for which the user no longer has access to the user-centric credential (i.e., alias) that was used to initially create the account, or that is currently linked to the account. This could occur if the user accidentally deleted the self-issued card they used to establish an account.

In the scenario presented in this article Tivoli Access Manager is used as the TFIM point of contact, and LDAP as the TAM user registry. Tivoli Access Manager administration API's are used for the user account operations.

Figure 1 presents a user-interaction diagram which describes the high-level self-registration process with email confirmation:

Figure 1. User interaction for self-registration with e-mail validation
Self-Registration Overview

Naturally there are several error conditions that must be catered for during this process, and that logic is best described with a flowchart as shown in Figure 2. Consider the START of this flowchart as the "Reject authentication, or initiate self-registration" process of the flowchart from the article on Replace Password Authentication on your Web site with an Information Card or OpenID.

Figure 2. Processing a user-centric credential for self-registration
Self-Registration Processing

A larger version of the flowchart image is available here.

When the user later visits this site and presents their user-centric credential the alias will be linked to their account. Recall that the processing rules that will authenticate the user have already been developed as part of the preliminary article: Replace Password Authentication on your Web site with an Information Card or OpenID. Remember that this article, and the code presented within it, is a superset of the work already done on linking user-centric credentials to an account.

Implementation and deployment notes

This section discusses a variety of implementation details, and alternatives available. By following along, you will also find instructions for deploying the solution to your own environment.

Implementation as an STS mapping module

The processing logic for the algorithm described above has been developed as a custom Java™ STS Mapping Module, extending the example from the previous article, and assuming the following:

  • Tivoli Access Manager is the point-of-contact. Because of this the TAM Java administration API's are used to provide account creation and modification functionality. A TAM GSO credential is associated with the user's account and used to store the alias and nonce during the self-registration or account recovery process. If you were using IBM WebSphere® as a point of contact and a different user registry you would need to re-write the user management pieces of the mapping module. These have been encapsulated into a separate interface to make that job easier.
  • E-mail notification is handled by the javax.mail API. Access to an SMTP server is needed to send the e-mails. The use can click on the link sent in the e-mail to complete self-registration or account recovery. You can actually test the functionality without an SMTP server; however, you will have to turn on tracing to see in the log the link that the email would contain.

The module has two pages of configuration information. The first is an init page. Recall that init pages contain one set of configuration per instance of the module, regardless of the number of trust chains or federations in which that instance is used. The init page will manage configuration parameters for:

  • A path to the pdjrte configuration file used for initializing the TAM Java Administration API. This API will be used for creating, deleting and modifying user accounts.
  • SMTP hostname and authentication parameters for sending outgoing email.

The init page looks like that shown in Figure 3:

Figure 3. Configuration parameters for the init page
Init Configuration Parameters

The full path to the pdjrte configuration file in the above figure is taken from the configuration file that TFIM uses internally. It is safe to use this file for the module. The actual path to the file will vary depending on your WAS profile and TFIM domain name. In my environment the full path is:
file:///opt/IBM/WebSphere/AppServer/profiles/idp/config/itfim/idp/nodes/localhostNode01Cell/localhostNode01/server1/amconfig.conf
Just look for a file under your WebSphere profile's config root called amconfig.conf, and you should find it. Alternatively, you can always run the TAM SvrSslCfg and create another TAM configuration file and use that.

There is also a self configuration page, which may have different options on a per-federation basis (though practically that is unlikely). The self page will manage configuration for:

  • A URL which represents the first part of "account confirmation link" for users who are being sent an email during the first phase of self-registration. This would be customized based on the hostname and junction names used in your environment.
  • A similar URL for "account recovery".
  • The prefix and suffix portions of the LDAP DN for new users.
  • The federation context id to use in the alias service (previously this was hard-coded to "myfedctx").
  • An optional group name to add successfully registered users to in TAM.

The self page looks like that shown in Figure 4:

Figure 4. Configuration parameters for the self page
Self Configuration Parameters

The full paths to the demonstration URL's shown above are:

  • Account Confirmation URL: https://www.ibmidentitydemo.com/FIM/LinkingEnablement/account_confirm.jsp?nonce=
  • Account Recovery URL: https://www.ibmidentitydemo.com/FIM/LinkingEnablement/account_recover.jsp?nonce=

The mapping module code will append the actual nonce, and some other query string parameters to these URL's when building email notifications. It is therefore important that the hostname and path to the enablement application is correct.

Displaying error and informational user messages from the STS

With the new processing logic in our mapping rule, there are several use cases where we may want to return an informative message to the user - but not display it like an exception. Good examples of this include:

  • When the user completes the first phase of self-registration and the module wishes to inform them an email has been sent
  • When the user completes the first phase of account recovery and the module wishes to inform them an email has been sent
  • If the user presents a bad nonce (e.g. they used an old email from a previous phase 1 registration or account recovery attempt)



In each of these cases it is desirable for the system to display an informative message rather than an exception stack trace. There are two main ways we could accomplish this goal - using either Exception Text Parsing, or a Special TAM Message User. Both are explained below. You can choose which is most appropriate for your purposes; however, the code accompanying this article implements the first approach.



Exception Text Parsing

With this approach to displaying an informative message, the mapping module throws an exception containing the message text, and surrounds the message text with special markers which indicate that the exception contains a message. JavaScript is then used in the error page (alternatively the escaped exception text could be auto-posted to a JSP/Servlet and then use Java) to detect from the markers that this is really an informative message rather than an error and render the page appropriately.

This is a quick approach, quite efficient and very easy to implement. The error pages used by the Information Card and/or OpenID functionality to display exception text are modified to look for text that contains the prefix ***BEGINMESSAGE*** and is terminated by the first occurrence of the suffix ***ENDMESSAGE***. If such a pattern exists, the message bounded by the markers will be displayed as an informative message. Otherwise the standard error page format will be displayed.

The modified version of the OpenID error page (see <FIM_install_root>/pages/C/openid/error.html) is shown in Listing 1, and the very similar modified version of the InfoCard error page (see <FIM_install_root>/pages/C/infocard/error_token_exchange.html) is shown in Listing 2. The only difference between the two listings is the page title, and the body of the ERROR_PAGE which is slightly different for OpenID and Information Card errors.

Listing 1. OpenID error page with informational message support (pages/C/openid/error.html)
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  <title>Message</title>
</head>
<body style="background-color:#ffffff">

<!--
    A hidden div that holds the error page contents.
    We'll display this content if the exception is a real error.
-->
<div id="ERROR_PAGE" name="ERROR_PAGE" style="display: none;">
  <div>
    <h2 style="color:#ff8800">An error has occurred</h2>
    <div id="infoDiv" style="background-color:#ffffff;color:#000000">
      <em>@REQ_ADDR@</em> <br />
      <em>@TIMESTAMP@</em> <br />
    </div>
    <br />
    <div id="detailDiv"
      style="background-color:#999999; border-style:solid; border-width:1px;
      border-color:#000000">
      <h4>Error details</h4>
      @DETAIL@
    </div>
    <br />
    <div id="stackDiv"
      style="background-color:#999999; border-style:solid; border-width:1px;
      border-color:#000000">
      <h4>Stack trace</h4>
      @EXCEPTION_STACK@
    </div>
  </div>
</div>

<script type="text/javascript">
  // utility function
  function showDiv(f) {
    if (f.style) {
      f.style.display='block';
    }
  }

  //
  // determine if this is a "message exception"
  // if it is, display the message, otherwise display an error
  //
  var exctext = document.getElementById("ERROR_PAGE").innerHTML;
  var msgprefix="***BEGINMESSAGE***";
  var msgsuffix="***ENDMESSAGE***";

  var msgstart = exctext.indexOf(msgprefix);
  var msgend = exctext.indexOf(msgsuffix);
  if (msgstart >= 0 && msgend > msgstart+msgprefix.length) {
    // it's a message - just display the message text
    document.write(exctext.slice(msgstart+msgprefix.length, msgend));
  } else {
    // it's an error - show the error
    document.title = "An OpenID Error has Occurred";
    showDiv(document.getElementById("ERROR_PAGE"));
  }
</script>
</html>
Listing 2. Information card error page with informational message support (pages/C/infocard/error_token_exchange.html)
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
  <title>Message</title>
</head>
<body style="background-color:#ffffff">

<!--
    A hidden div that holds the error page contents.
    We'll display this content if the exception is a real error.
-->
<div id="ERROR_PAGE" name="ERROR_PAGE" style="display: none;">
    <div>
      <h2 style="color:#ff8800">The security token exchange failed</h2>
      <div id="infoDiv" style="background-color:#ffffff;color:#000000">
        <em>@REQ_ADDR@</em> <br />
        <em>@TIMESTAMP@</em> <br />
      </div>
      <br />
      <div id="detailDiv"
        style="background-color:#999999; border-style:solid; border-width:1px;
        border-color:#000000">
        <h4>Error details</h4>
        The received security token could not be exchanged for the user's security
        credentials at this Web site.
        <ul>
          <li>The security token may have expired or is otherwise invalid.</li>
          <li>The security claims are insufficient to establish a user credential.</li>
          <li>The issuer of the security token is not acceptable.</li>
          <li>The security token type is not supported.</li>
        </ul>
      </div>
      <br />
      <div id="stackDiv"
        style="background-color:#999999; border-style:solid; border-width:1px;
        border-color:#000000">
        <h4>Stack trace</h4>
        @EXCEPTION_STACK@
      </div>
    </div>
</div>

<script type="text/javascript">
  // utility function
  function showDiv(f) {
    if (f.style) {
      f.style.display='block';
    }
  }

  //
  // determine if this is a "message exception"
  // if it is, display the message, otherwise display an error
  //
  var exctext = document.getElementById("ERROR_PAGE").innerHTML;
  var msgprefix="***BEGINMESSAGE***";
  var msgsuffix="***ENDMESSAGE***";

  var msgstart = exctext.indexOf(msgprefix);
  var msgend = exctext.indexOf(msgsuffix);
  if (msgstart >= 0 && msgend > msgstart+msgprefix.length) {
    // it's a message - just display the message text
    document.write(exctext.slice(msgstart+msgprefix.length, msgend));
  } else {
    // it's an error - show the error
    document.title = "An Information Card Error has Occurred";
    showDiv(document.getElementById("ERROR_PAGE"));
  }
</script>
</html>

You should update the pages in the <TFIM_install_root>/pages directory and re-publish pages using the TFIM Console under Domain Management->Runtime Node Management. Note that copies of these file can also be found embedded within WEB-INF directory of the enablement application available in the Downloads section.



Special TAM Message User

With this approach to displaying informational user messages (which again will not be used in this article), when the STS module wants to display a message it actually performs a TAM login as a special TAM user you would need to establish called message, setting the desired message display text as a tagvalue_message extended attribute in the message user's credential. The TAM ACL policy on WebSEAL would have to be configured such that the message user does not have access to any page except for a special displayMessage.jsp page on the enablement application. WebSEAL would need to be configured to send the tagvalue_message credential attribute as a HTTP header called "message" to the enablement application. When WebSEAL detects the user is logged in (as the message user), but forbidden to access the desired target resource, WebSEAL will attempt to display the built-in forbidden page from the errors directory (38cf0427.html). The forbidden page can be re-written to auto-post to the displayMessage.jsp, as shown in Listing 3:

Listing 3. Auto-forwarding the TAM forbidden page and parameters to a JSP
<html>
<form action="/FIM/LinkingEnablement/displayMessage.jsp" method="post">
<input type="hidden" name="USERNAME" value="%USERNAME%" />
</form>
<script TYPE="text/javascript">
    var displayText = 'Please wait...';
    document.write(displayText);
    setTimeout('document.forms[0].submit()', 0);
</script>
</html>

The displayMessage.jsp page detects that the user is the "message" user, and renders a message page instead of the normal forbidden text. The page should also contain a hidden image tag to the /pkmslogout link if the message user is detected - this will automatically terminate that user's session.

The sample enablement application in the Downloads section contains a displayMessage.jsp to show you how this might be done; however, we do not utilize that page for the actual demonstrations shown in this article. The previous technique using Exception Text Parsing to render the messages from the error page is simpler and easier to implement.

Updates to WebSEAL login page

The WebSEAL login page used for this article has undergone some major renovations. In particular:

  • The Information Card and OpenID login forms now require an email address be supplied.
  • The TARGET parameter for both the Information Card and OpenID login forms was previously hard-coded to the URL of the welcome.jsp page of the enablement application. The TARGET is now automatically determined from the WebSEAL replacement macros: %HTTPS_BASE%%URL%. This will automatically populate the TARGET with a https-based URL representing the object the user was trying to access when they were prompted to login. This implies that the WebSEAL is configured for https access only.
  • There is some JavaScript at the bottom of the page which will automate authentication form posting for users who are completing the second phase of a self-registration or account recovery operation. This detection is done based on the TARGET URL and its query-string parameters. This URL is in the email sent to the user after completing the first phase of self-registration or account recovery.
  • A <div> tag with the id LOGIN_PAGE is used to wrap the actual login form HTML and is initially hidden. It is only displayed when we are sure there is no need to automate the posting of a login form.
  • The Information Card and OpenID login forms are now labeled "Login, Self-Register, or Recover your existing account..." as the functionality in the STS mapping code now handles all these cases concurrently.

The complete listing of the new WebSEAL login.html is shown in Listing 4:

Listing 4. WebSEAL login form - login.html
<!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">
  <link type="text/css" rel="stylesheet" href="/theme/Master.css">
  <title>Login</title>
</head>
<body bgcolor="#FFFFFF" text="#000000">

<div id="LOGIN_PAGE" name="LOGIN_PAGE" style="display: none;">

<b>Access Manager for e-business Login</b>
<br />

%ERROR%
<br /><br />

<!--- DO NOT TRANSLATE OR MODIFY any part of the hidden parameter(s) --->

<!---
  The following block of code provides users with a warning message
  if they do not have cookies configured on their browsers.
  If this environment does not use cookies to maintain login sessions,
  simply remove or comment out the block below.
--->


<!--- BEGIN Cookie check block --->
<!---
DO NOT TRANSLATE anything inside the SCRIPT tag except the quoted
string warningString.  i.e. var warningString = "Translate this string";
--->
<script type="text/javascript">
var warningString = "<b>WARNING:</b> To maintain your login session, " +
"make sure that your browser is configured to accept Cookies.";
document.cookie = 'acceptsCookies=yes';
if(document.cookie == ''){
document.write(warningString);
}
else{
document.cookie = 'acceptsCookies=yes; expires=Fri, 13-Apr-1970 00:00:00 GMT';
}
</script>
<noscript>
<b>WARNING:</b> To maintain your login session, make sure that<br />
your browser is configured to accept Cookies.
</noscript>
<!--- END Cookie check block --->


Login with a username and password:
<form method="POST" action="/pkmslogin.form">
<font SIZE="+2">
<table border="0" width="400">
<tr>
<td align="LEFT"><ul><li>Username</li></ul></td>
<td><input name="username" size="15"></td>
</tr>
<tr>
<td align="LEFT"><ul><li>Password</li></ul></td>
<td><input type="PASSWORD" name="password" size="15"></td>
</tr>
</table>
</font>

<input type="HIDDEN" name="login-form-type" value="pwd" />

<input type="SUBMIT" value="Login">
</form>
<hr />
OR Login, Self-Register or Recover your existing account with an Information Card:<br />
<form id="infocard_login" method="post"
  action="https://www.ibmidentitydemo.com/FIM/sps/infocardsp/infocard/login">
  <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
 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress"
   name="requiredClaims">
<param value="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname
 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname
 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/streetaddress
 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/locality
 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/stateorprovince
 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/postalcode
 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/country
 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/homephone
 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/otherphone
 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mobilephone
 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/dateofbirth
 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/gender
 http://schemas.xmlsoap.org/ws/2005/05/identity/claims/website
 http://www.ibmidentitydemo.com/claims/assurancelevel" name="optionalClaims">
  </object>
  <input name="TARGET" type="hidden" value="%HTTPS_BASE%%URL%">
  <img height="16" width="23" src="/images/infocard_23x16.png">&nbsp;&nbsp;
  <input value="[Information Card Login]" class="submitLink" type="submit">
</form>
<hr />
OR Login, Self-Register or Recover your existing account with an OpenID:<br />
<form id="openid_login" method="post"
  action="https://www.ibmidentitydemo.com/FIM/sps/openidsp/openid/login">
  <input value="checkid_setup" name="openid.mode" type="hidden">
  <input value="nickname,fullname,dob,gender,postcode,country,language,timezone"
    name="openid.sreg.optional" type="hidden">
  <input value="email" name="openid.sreg.required" type="hidden">
  <input value="http://www.ibm.com" name="openid.sreg.policy_url" type="hidden">
  <input name="TARGET" type="hidden" value="%HTTPS_BASE%%URL%">
  <input name="openid_identifier" class="openid" type="text">&nbsp;&nbsp;
  <input value="OpenID Login" type="submit">
</form>

</div>

<script type="text/javascript">
  // utility functions
  function QueryString(str) {
    this.params = {};

    if (str != null && str.length > 0) {
      // replace + with space
      str = str.replace(/\+/g, ' ');

      // split name=value arguments
      var pairs = str.split('&');

      // split each pair
      for (var i = 0; i < pairs.length; i++) {
        var arg = pairs[i].split('=');
        var name = unescape(arg[0]);

        var value = (arg.length==2)
          ? unescape(arg[1])
          : name;
        if (name != null && name.length > 0 &&
          value != null && value.length > 0) {
          this.params[name] = value;
        }
      }
    }
  }

  QueryString.prototype.get = function(name) {
    return this.params[name];
  }

  function showDiv(f) {
    if (f.style) {
      f.style.display='block';
    }
  }

  //
  // determine if this is an account confirmation or recovery operation
  // if it is, automate the login prompting, otherwise prompt manually with
  // normal login form
  //
  var target = "%HHTPS_BASE%%URL%";
  var confirmation="/FIM/LinkingEnablement/account_confirm.jsp?nonce=";
  var recovery="/FIM/LinkingEnablement/account_recover.jsp?nonce=";

  if (target.indexOf(confirmation) >= 0 || target.indexOf(recovery) >= 0) {
    // this is account confirmation or recovery - automate the login
    var qs = new QueryString(target.substr(target.indexOf("?")+1));
    var mode = qs.get("mode");

    if (mode == "openid") {
      // submit openid login form automatically
      var f = document.getElementById("openid_login");
      f.openid_identifier.value = qs.get("openid.identity");
      f.submit();
    } else {
      // submit infocard login form automatically
      var f = document.getElementById("infocard_login");
      f.submit();
    }
  } else {
    // display normal login form
    showDiv(document.getElementById("LOGIN_PAGE"));
  }

</script>

</body>
</html>

You should verify and update if necessary the following pieces of the login.html and copy to your WebSEAL:

  • The form action URLs for the OpenID and/or InfoCard endpoints in the login forms if your federations have different names.
  • The Javascript confirmation and recovery variables which have paths to pages of the enablement application.


Note that a copy of this file can also be found embedded within WEB-INF directory of the enablement application available in the Downloads section.

Updates to Enablement Application

The linkingenablement.ear application available in the Downloads section is a direct extension of the application built for the previous article Replace Password Authentication on your Web site with an Information Card or OpenID. This application should be installed on a WebSphere junctioned behind WebSEAL. A good place for testing purposes is to install it on the same WebSphere where the TFIM Runtime is installed.

The enablement application contains an embedded configuration file called linkingenablement.properties that you can edit after the application is installed. It contains several links that you should update to reflect your own environment. The file contains comments that describe each of the configurable parameters.

The enablement application has undergone a few minor updates:

  • The welcome.jsp now includes links to view your credential using the EPAC jsp from this tutorial. You will need to hand-modify the epac.jsp to point to the correct location of a TAM Java configuration file for it to work.
  • The welcome.jsp also includes a Logout link, which performs a WebSEAL logout.
  • The application contains new pages account_confirm.jsp and account_recover.jsp which act as landing pages for the email confirmation phase of self-registration or account recovery.
  • The application also contains an example displayMessage.jsp that is not used by the scenario described in this article. It is provided as an example related to the Special TAM Message User technique for displaying information user messages from the STS Mapping module java code.
  • The WEB-INF directory contains reference copies of the WebSEAL Login page, and the error pages for OpenID and information card errors used to display informative messages to the user.

Usage demonstrations

This section contains links to animated demonstrations showing how the functionality of the mapping module looks from an end-user perspective.

Quick deployment instructions

This is a bullet-list of things you need to do to deploy the solution. These assume you have a TAM/TFIM environment configured with WebSEAL as the TFIM point-of-contact, and the alias service configured:

  • Deploy the linkingenablement.ear application to the same WebSphere running the TFIM runtime. After it is deployed, update the linkingenablement.properties file embedded in the application with URL values appropriate to your environment. You will also need to update the path to the PDJRTE configuration file embedded in the epac.jsp page.
  • Deploy the com.tivoli.am.fim.demo.selfregistration_1.0.0.jar TFIM plug-in to the TFIM Runtime. You should copy it to <TFIM_install_root>/plugins, then use the console to Publish Plug-ins. You will need to refresh the management service after doing this.
  • Create a module instance of the self registration STS module, and set the init configuration parameters for the PDJRTE config file and SMTP server.
  • Create an OpenID and/or InfoCard service provider federation. To match those used in the sample configurations, call the federations "openidsp" and "infocardsp" respectively. When configuring the mapping rule for the federations, use the self registration custom module instance created in the previous step. During that process you will be prompted to set the configuration parameters for the mapping module. The first two URL's and the DN prefix/suffix are the main things to change.
  • Use the tfimcfg.jar utility to update the TAM policy for the federations.
  • In a subdirectory under the WEB-INF directory of the deployed enablement application you will find a replacement webseal_login.html and the replacement error pages for the OpenID and Information Card error pages. These need to be copied into place. The webseal_login.html may need to be updated with the correct federation endpoints and path to the linking enablement application. It should be copied to your WebSEAL server, and replaces the existing login.html file. The other files go to the corresponding pages directory of your TFIM installation, and then you Publish Pages using the TFIM console.
  • Access the welcome.jsp of the enablement application with a browser and start testing. In my environment, that URL is: https://www.ibmidentitydemo.com/FIM/LinkingEnablement/welcome.jsp.
  • Remember there is detailed trace available in the code of the mapping module (set your trace string to include com.tivoli.am.fim.demo.*=all). All the source code is also included in the plug-in jar.

Further work

This section describes some design limitations and opportunities for further expanding on the self-registration, account recovery, and user-centric identity linking work presented in the article.

Allowing Multiple User-Centric Aliases

The current implementation (by design) permits you to have only one linked user-centric alias at a time per federation context id. If you create both an OpenID relying-party federation and an information card relying-party federation, you can configure them to share a common federation context id (currently defaulted to "myfedctx") or to use separate contexts. If they use the same federation context id then only one user-centric alias (of either type) can be associated with the account at a time. If you use a different federation context id for each federation, you can have both a linked OpenID and a linked information card. Note that even with this configuration there is still only one of each type.

It is not too difficult to modify the code presented in this article to support multiple concurrent aliases for a single user account and federation context id. The alias service supports this notion, as does the functions provided in the IDMappingExtUtils class. This is left as an exercise for the reader if interested.

Half-baked accounts

As with all self-registration processes, it's quite likely that some people will try to use a fake email address. In that case they won't be able to receive the confirmation email and there will be an account left in the disabled state in the user registry that will never be fully registered. It makes sense to have a process which from time to time cleans up those accounts. Tivoli Identity Manager and its lifecycle rules may be employed to cater for this situation if Tivoli Identity Manager is being used to manage accounts in the TAM environment.

Conclusions

This article and its predecessor have demonstrated at least three valid use cases for user-centric identity in an Identity and Access Management solution:

  • Using user-centric identities to replace password authentication at a Web site
  • Self-registration to a Web site with a user-centric identity using email address validation
  • Automated account recovery at a Web site with a user-centric identity using email address validation

There are plenty of ways to extend this set of capabilities to provide additional levels of assurance and validation; however, even in its current basic form the capabilities demonstrated in this article provide significant ease-of-use advantages to consumers, and lower cost-of-ownership to the administrators as the user is in control of establishing (and recovering) their own account without the need for helpdesk interaction.


Downloads

DescriptionNameSize
User-Centric Custom Java Mapping Modulecom.tivoli.am.fim.demo.selfregistration_1.0.0.jar43KB
Enablement Pageslinkingenablement.zip21KB

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=336457
ArticleTitle=User Centric Identity with Tivoli Federated Identity Manager, Part 2: Self registration and account recovery using information cards and OpenID
publish-date=10152008