Managing OpenID trusted sites with Tivoli Federated Identity Manager

Writing your own trusted sites manager

IBM® Tivoli® Federated Identity Manager 6.2 (TFIM) introduces support for OpenID 1.1 and 2.0 authentication protocols. When configured in the role of an OpenID Provider (Identity Provider), TFIM allows end users to record choices about authenticating to trusted relying-party sites. For example a user may select "Allow authentication forever" to a particular relying-party, and may select which attributes they are willing to share with that site. By default TFIM stores these choices in persistent cookies on the user's browser. The cookie technique is effective, but not portable for users across different browsers. This article will demonstrate how to write your own plug-in for the storage and retrieval of user choices (for example to a database) via the TFIM TrustedSitesManager extension point.

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.


developerWorks Professional author
        level

Eduardo A. Solis, Software Developer, IBM

Eduardo SolisEduardo Solis is a software engineer with the IBM Tivoli Federated Identity Manager development team. Before joining the TFIM team he worked on data protection and disaster recovery solutions. He holds a Bachelor in Computer Engineering from ITESM-CEM in Mexico and a M.E. in Software Engineering from the University of Texas at Austin.



15 October 2008

Pre-requisite knowledge

This is an advanced article designed for developers who have a need to customize (typically centralize) the storage model for user preferences of an OpenID provider deployment using Tivoli Federated Identity Manager 6.2. Readers should:

  • Be familiar with OpenID authentication using TFIM as an OpenID provider.
  • Be comfortable with Java™ development.
  • Have read and worked through the TFIM 6.2 STS Module Development Tutorial
  • Have access to a TFIM 6.2 Runtime environment with Fixpack 1 installed. Fixpack 1 is a requirement for building your own TrustedSitesManager implementation.

Introduction

TFIM as an OpenID provider

Initially let's review the major user interaction points with TFIM as an OpenID provider, and how these interaction points relate to the management of a list of a user's trusted and untrusted sites.

Figure 1 presents the basic OpenID authentication flow:

Figure 1. OpenID authentication overview
OpenID Authentication Overview

Between steps 3 and 4 of the authentication flow the user's trusted sites preferences are consulted to determine if the user permits authentication to the relying party. If the user does not have a stored preference, they are prompted to determine if authentication should be permitted. When using TFIM as the OpenID provider the user is shown a customizable page called <page_root>/openid/consent.html, which looks like that shown in Figure 2:

Figure 2. OpenID consent to authenticate
OpenID Consent to Authenticate

As can be seen from Figure 2, the user is prompted for whether or not they wish to permit authentication to this site (one-time or permanent), and in the case of "yes", which set of simple registration extension (SREG) attributes the user is willing to share with this particular relying party. If the user selects either Allow authentication forever or Do not ever authenticate to this site, that decision should be persistently stored so that prompting is not necessary during future authentication attempts.

Further, if the decision is Allow authentication forever, the user's optional attribute preferences and "user data" should be remembered as well. The "user data" field is an optional field which can indicate a persona index or some other information useful to the OpenID Provider when populating attribute values. Note that required attributes are considered always consented if a user consents to authentication at the site.

There is one other interface for users related to their trusted sites information. If a user has stored a decision about a particular trusted site, they may wish to change that decision. When using TFIM as the OpenID Provider (OP), there is an endpoint which allows user's to view and modify their trusted sites information. The customizable page which presents this interface is located at <page_root>/openid/sitemanager.html, and can be accessed with the URL:

https://idp.com/FIM/sps/<fedname>/openid/sites

An example of the trust sites manager in action can be seen in Figure 3:

Figure 3. OpenID trusted sites manager
OpenID Trusted Sites Manager

In the example shown in Figure 3 you can see that the user has selected to trust the PHP test endpoint at openidenabled.com, and trust www.openiddirectory.com (but only share fullname and nickname), and has decided to never authenticate to the Ruby test endpoint at openidenabled.com. Note: These selections are for example purposes only!

In each case the trusted sites manager allows you to remove the persistent decision. If a persistent decision is removed you will be prompted for a new authentication decision on the next single sign-on attempt to that site.

TFIM encapsulates the storage and query of a user's trusted sites preferences in an interface called the TrustedSitesManager. This interface will be described in detail later in this article. The default implementation in TFIM 6.2 stores user preferences as serialized objects in persistent cookies on the user's browser. This can be seen by looking at the cookie manager on your browser, or displaying cookies when connected to the TFIM OpenID Provider site, as shown in Figure 4:

Figure 4. Trusted sites as cookies
Trusted Sites as Cookies

It is not important to understand the semantics of these particular cookies. Instead, recognize that cookies are used to store the user preferences and that if a user moves browsers or deletes their cookies, all existing trusted sites preferences will be unavailable and the user will be re-prompted for consent to authenticate. Additionally cookies will not scale well to large numbers of relying-party sites.

The rest of this article outlines the interface to writing your own trusted sites manager and guides you through two examples - one is a simplistic memory-based implementation which serves only to demonstrate a minimalist implementation and introduce the interface. The other uses a Java Database Connectivity (JDBC) interface to centrally store trusted sites information.

The trusted sites manager interface

The TrustedSitesManager interface is an integration point which allows developers to implement their own storage model for OpenID trusted sites information and user preferences. Complete Javadoc for the interface can be found in the <FIM_install_root>/docs/com.tivoli.am.fim.protocols directory of your TFIM installation. There are four methods to implement in the interface, as follows:

  • TrustedSitesManager.TrustedSiteInformation getTrustedSiteInformation(String username, String trustRoot, HttpServletRequest req)
    This interface allows the TFIM runtime to retrieve trusted site information for a particular relying-party site (identified by trustRoot) for a particular user. This will be used by TFIM at runtime during authentication to determine if prompting for consent-to-authenticate is needed. The returned object will contain a TrustLevel indicating if authentication consent has been persistently recorded and what the user's preferences are. If there is no information available for the site (e.g., first attempt to authenticate), the implementation should create a new temporary TrustedSitManager.TrustedSiteInformation object and set the trust level within that object to TrustLevel.UNKNOWN. The HttpServletRequest is made available in case the implementation wishes to access other request parameters such as cookies.
  • void setTrustedSiteInformation(TrustedSitesManager.TrustedSiteInformation siteInfo, HttpServletRequest req, HttpServletResponse rsp)
    This interface is called by the TFIM Runtime after a user has made a permanent (permit-always or deny-always) decision about a particular relying-party site on the consent-to-authenticate page. The implementation can determine who the user and relying-party site is, as well as the user's selections from the siteInfo parameter. The implementation should store all the information from the siteInfo parameter such that it can later be retrieved by indexing on either just the username, or also on the username and the trusted site (i.e., trustRoot). The HttpServletRequest and HttpServletResponse objects are made available in case the implementation wishes to access and set other request/response parameters such as cookies.
  • TrustedSitesManager.TrustedSiteInformation[] getTrustedSitesForUser(String username, HttpServletRequest req)
    This interface is called by the Trusted Sites Manager in the TFIM Runtime. The Trusted Sites Manager allows a use to view and modify all their persistently recorded trusted and un-trusted sites, as previously shown in Figure 3. Indexed on the username, the implementation should return all known persistently recorded site and user preference information as an array of TrustedSitesManager.TrustedSiteInformation objects. The HttpServletRequest is made available in case the implementation wishes to access other request parameters such as cookies.
  • void removeTrustedSiteInformation(String username, String trustRoot, HttpServletRequest req, HttpServletResponse rsp)
    This interface is used by the Trusted Sites Manager implementation in the TFIM Runtime, and will be called when a user has selected to delete the persistently recorded user preferences for a particular relying-party site (identified by trustRoot). The implementation should delete the user preference information for that site for the give user.

In addition to the above four methods, your implementation class must provide a default constructor (i.e., a constructor that takes no parameters).


A minimal implementation using in-memory storage

TFIM 6.2 actually ships an in-memory implementation (the module ID is TrustedSitesManagerMemoryImpl) very similar to that shown below, but is not configured to use it. The in-memory implementation only serves as a simplistic example of how to implement a trusted sites manager, and can be built upon to use a real persistence model. The full source for the in-memory implementation is shown in Listing 1:

Listing 1. In-memory implementation of a TrustSitesManager
package com.tivoli.am.fim.demo.trustedsitesmanager;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

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

import com.tivoli.am.fim.openid.provider.TrustedSitesManager;

/**
 *
 * Implements a very simplistic trusted sites manager that stores
 * all user preferences in an in-memory map. This is not useful for
 * a production deployment, but serves as a simple starting point for
 * a developer wishing to implement their own centralized storage model
 * for trusted sites information.
 *
 * @author shane
 *
 */
public class TrustedSitesManagerMemoryImpl implements TrustedSitesManager {

  final static String CLASS = TrustedSitesManagerMemoryImpl.class.getName();

  Logger _log = Logger.getLogger(CLASS);

  Map /* String->TrustedSiteInformation */_trustedSites;

  public TrustedSitesManagerMemoryImpl() {
    _trustedSites = Collections.synchronizedMap(new HashMap());
  }

  public synchronized TrustedSiteInformation[] getTrustedSitesForUser(
    String username,
    HttpServletRequest req) {

    String methodName = "getTrustedSitesForUser";
    TrustedSiteInformation[] result = new TrustedSiteInformation[] {};
    _log.entering(CLASS, methodName, new Object[] { username });
    try {
      List sitesForUser = new ArrayList();
      Collection values = _trustedSites.values();
      if (values != null && !values.isEmpty()) {
        for (Iterator i = values.iterator(); i.hasNext();) {
          TrustedSiteInformation tsi = (TrustedSiteInformation) i.next();
          if (tsi.getUsername().equals(username)) {
            sitesForUser.add(tsi);
          }
        }
      }
      if (sitesForUser.size() > 0) {
        result = new TrustedSiteInformation[sitesForUser.size()];
        for (int j = 0; j < sitesForUser.size(); j++) {
          result[j] = (TrustedSiteInformation) sitesForUser.get(j);
        }
      }
    } finally {
      _log.exiting(CLASS, methodName, result);
    }
    return result;
  }

  public synchronized TrustedSiteInformation getTrustedSiteInformation(
    String username,
    String trustRoot,
    HttpServletRequest req) {

    String methodName = "getTrustedSiteInformation";
    TrustedSiteInformation result = null;
    _log.entering(CLASS, methodName, new Object[] { username, trustRoot });
    try {
      String key = generateKey(username, trustRoot);
      result = (TrustedSiteInformation) _trustedSites.get(key);
      if (result == null) {
        result = new TrustedSiteInformation(username, trustRoot,
          TrustLevel.UNKNOWN, false, null, null);
      }
    } finally {
      _log.exiting(CLASS, methodName, result);
    }
    return result;
  }

  public synchronized void setTrustedSiteInformation(
    TrustedSiteInformation siteInfo,
    HttpServletRequest req,
    HttpServletResponse rsp) {

    String methodName = "setTrustedSiteInformation";
    _log.entering(CLASS, methodName, new Object[] { siteInfo });
    try {
      String key = generateKey(siteInfo.getUsername(), siteInfo.getTrustedSite());
      _trustedSites.put(key, siteInfo);
    } finally {
      _log.exiting(CLASS, methodName);
    }
  }

  public synchronized void removeTrustedSiteInformation(
    String username,
    String trustRoot,
    HttpServletRequest req,
    HttpServletResponse rsp) {

    String methodName = "removeTrustedSiteInformation";
    _log.entering(CLASS, methodName, new Object[] { username, trustRoot });
    try {
      String key = generateKey(username, trustRoot);
      _trustedSites.remove(key);
    } finally {
      _log.exiting(CLASS, methodName);
    }
  }

  String generateKey(String username, String trustedSite) {
    String result = username + "_" + trustedSite;
    return result;
  }
}

Designing a simple JDBC implementation

The first step in designing a JDBC™ implementation is to actually choose a relational database and create a database schema. For simplicity reasons this tutorial will use the Apache Derby database embedded in WebSphere® Application Server. This embedded database is configured and ready to use in a J2EE™/JDBC environment.

For the database schema, we decided to use a single table to represent the data stored in the TrustedSiteInformation object as shown in Figure 5.

Figure 5. A simple Trust Site database table
A simple Trust Site database

The data contents for each column is explained in Table 1.

Table 1. Column names and data contents
Column NameData type
IdArtificial primary key for the table
UsernameStores the username who owns the OpenId identifier.
TrustRootContains the relying party URL that is requesting the OpenID assertion
TrustLevelStores the value of the trust level converted to a string
Optional_Attributes_AllowedRepresents a Boolean that specifies if all optional attributes can be passed to the Relying Party
Optional_AttributesA comma separated list of attributes that can be passed to the Relying Party if all attributes are not allowed
UserDataStores the userdata field which contains optional persona information

Developing a trusted sites manager extension

This section will guide you through the development process for creating an Open Services Gateway Initiative (OSGi) plug-in for TFIM which includes an implementation of an XMLExtensionProvider.

The starting point for implementation should be to establish an Eclipse workspace for TFIM plug-in development. There is a detailed tutorial on developing a custom plug-in for STS modules called the TFIM 6.2 STS Module Development Tutorial which you are expected to be familiar with as a pre-requisite to this article. You can use exactly the same workspace established for that tutorial to develop other TFIM plug-ins, including implementations of the openid_trusted_sites_manager. This article will begin with instructions that assume you have a plug-in development environment established with the Target Platform pointing to the ITFIM plugins directory.

Create a new Plug-in Project in your IDE, as shown in Figure 6 then press Next.

Figure 6. Project wizard - Create a new plug-in project
Project Wizard - Create a new Plug-in Project

Give the project a name (com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager), and select the other options as shown in Figure 7, then press Next:

Figure 7. Project wizard - Project name
Project Wizard - Project Name

Disable the plug-in options as shown in Figure 8, then press Next:

Figure 8. Project Wizard - Project options
Project Wizard - Project Options

There is no need to use a template, so disable that as shown in Figure 9, then press Finish:

Figure 9. Project wizard - Project template
Project Wizard - Project Template

You should now see the plug-in manifest editor. Navigate to the Dependencies tab, and add the com.tivoli.am.fim.common (6.2.0.0) and com.tivoli.am.fim.protocols (6.2.0.0) plug-ins as required dependencies press OK:

Figure 10. Manifest editor - Dependencies
Manifest Editor - Dependencies

Navigate now to the Extensions tab and add a new extension of type com.tivoli.am.fim.protocols.openid_trusted_sites_manager as shown in Figure 11:

Figure 11. Manifest editor - Add an extension
Manifest Editor - Add an Extension

Set an ID and Name for the module (our example uses jdbctrustedsitesmanager and Example OpenID Trusted Sites Manager using JDBC respectively), then right-click on the extension and define a new module. Configure properties for the module definition, as follows:

  • exposedClass - This is the class name of the class we will use to implement the extension. The Downloads section contains the source for this class, and the class name to use is com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager.TrustedSitesManagerJDBCImpl
  • version - Set this to 1.0.0

The module should look like that shown in Figure 12:

Figure 12. Manifest editor - Define module parameters
Manifest Editor - Module parameters

Save the changes at this point, then right-click on the src folder and select New -> Package as show in Figure 13:

Figure 13. New source package
New Source Package

Set the new package name to com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager then press Finish, as shown in Figure 14:

Figure 14. Name the package
Name the Package

Add a new Class to the package called TrustedSitesManagerJDBCImpl, and insert the source code from TrustedSitesManagerJDBCImpl.java in the Downloads Section. You should see a compile error (if necessary, switch to a Java perspective) indicating that the javax.servlet.http.HttpServletRequest class cannot be resolved, as shown in Figure 15:

Figure 15. Class resolution error
Class Resolution Error

This error is to be expected, and is typical of the TFIM plug-in development process. To correct it you can follow the instructions described in the TFIM 6.2 STS Module Development Tutorial, in particular the page entitled Advanced Development Considerations. To shortcut that process, here are the required steps:

  • Ensure that your com.tivoli.am.fim.sdk project includes j2ee.jar, and that the Export-Package stanza of the com.tivoli.am.fim.sdk project exports javax.servlet.http, as shown in Figure 16:
    Figure 16. Exporting javax.servlet.http from com.tivoli.am.fim.sdk
    Exporting javax.servlet.http from com.tivoli.am.fim.sdk
    Note: The com.tivoli.am.fim.osgi.connector_6.2.0.0 package already exports javax.servlet.http, so there is no need to generate a new MANIFEST.MF for the com.tivoli.am.fim.osgi.connector_6.2.0.0 plug-in.
  • Switch back to the Manifest editor for the com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager project, and add javax.servlet.http as an imported package, as shown in Figure 17:
    Figure 17. Importing javax.servlet.http to com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager
    Importing javax.servlet.http to com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager
  • That may be enough to fix it; however, due to an anomaly in the Eclipse platform, it's likely that your project will still not compile properly. Expand your custom plug-in project in the Java or Plug-in Development perspective, and verify if the com.tivoli.am.fim.sdk project is automatically listed under your plug-in project's Plug-in Dependencies list. If com.tivoli.am.fim.sdk is not, but org.eclipse.osgi bundle is listed, you will still have compile errors in your custom plug-in, and need to perform the following trick to fix it:
    • To fix this in the Eclipse 3.3 IDE, go to Windows->Preferences->Plug-in Development->Target Platform. Uncheck org.eclipse.osgi from the list of plug-ins and click "OK".
    • To fix this in the Eclipse 3.2 IDE (including Rational Software Architect 7) go to Windows->Preferences->Plug-in Development->Target Platform. Uncheck org.eclipse.osgi from the list of plug-ins and click "Apply", then recheck the org.eclipse.osgi plug-in, and click "OK". You will have to do this again whenever you restart Eclipse 3.2.
    Your custom plug-in project's Plug-in Dependencies should now show com.tivoli.am.fim.sdk instead of org.eclipse.osgi, and your compile errors should have resolved, as shown in Figure 18:
    Figure 18. Verify com.tivoli.am.fim.sdk in dependencies
    Verify com.tivoli.am.fim.sdk in Dependencies

The development of the plug-in is now complete - all that remains is to package, deploy and test the module.


Packaging your custom extension

Now that development of the module is complete we need to package the file into a jar that can be deployed to the TFIM 6.2 environment. This is done exactly as described in the TFIM 6.2 STS Module Development Tutorial. Be particularly mindful to use the existing MANIFEST.MF from your project rather than automatically generating the MANIFEST.MF file for the jar. For the purposes of this article we recommend exporting the project as a jar file named: com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager_1.0.0.jar. Alternatively you can download our pre-built demo from the Downloads section of this article.


Deploying your Custom Extension

In order to deploy and test your custom extension you have to perform three steps:

  1. Prepare a Derby Database.
  2. Create a JDBC Data Source for the Derby Database.
  3. Deploy your plug-in.

Prepare a Derby database

In order to prepare the Derby database for testing you need to have Derby installed on the system that will act as your database server. As we mentioned in a previous section this example uses the embedded Derby database installation that comes with the WebSphere Application server. You can use a different installation of Derby but need to change some of these steps accordingly.

To create the database we are using the ij utility that comes with Derby. Run this utility located in: WASHOME/derby/bin/embedded. Execute the command ij.sh (for Unix) or ij.bat (for Windows) to start the ij prompt.
ij version 10.1
ij>

Once in the prompt, create the database by typing the Derby command shown in Listing 2:

Listing 2. Command to create the Derby database
      CONNECT 'jdbc:derby:OpenIdTrustSiteDB;create=true';

When the command executes you will be connected to the OpenIdTrustSiteDB. Now create the table that represents an OpenId trusted site entry by running the SQL statement shown in Listing 3:

Listing 3. SQL statement to create the TrustSite table
      CREATE TABLE USERTOTRUSTSITE
        (Id int generated always as identity constraint ord_pk primary key,
         Username VARCHAR(1024) not null,
         TrustRoot VARCHAR(2048) not null,
         TrustLevel VARCHAR(256),
         Optional_Attributes_Allowed SMALLINT,
         Optional_Attributes VARCHAR(2048),
         UserData VARCHAR(2048));

Exit the ij tool (with the command: exit;) and proceed to create a JDBC Data provider.

Create a JDBC data source for your database

The JDBC data source will provide a JNDI name to access your database allowing you to separate the actual database details from your application code. In order to create the data source follow these steps:

  1. Navigate to the data sources panel in the WebSphere Application Server Integrated Solutions Console: Resources->JDBC->Data Sources.
  2. In the data sources panel select the desired scope for your data source, as shown in Figure 19.
  3. Click New to start a new data source wizard
    Figure 19. Data sources panel
    Data sources panel
  4. In the first step of the wizard enter a name for the data source and a JNDI name. It is very important that the JNDI name matches the one you are using in the code. Part of the source code from TrustedSitesManagerJDBCImpl.java has been reproduced here in Listing 4 for reference:
    Listing 4. Line of code that performs the JNDI lookup for the data source.
    JndiLookupAction lookup = new JndiLookupAction("jdbc/OpenIdTrustSiteDb");

    Be sure to enter this name as the JNDI name as shown in Figure 20:
    Figure 20. Data source wizard - step 1.
    Data source wizard - step 1
  5. In the second step of the wizard select the JDBC provider for the database. IBM WebSphere® will already have a Derby database provider so select that one.
    Figure 21. Data source wizard - step 2.
    Data source wizard - step 2
  6. In the third step o the wizard you need to provide the actual file system path to the database. If you are using the embedded Derby as in Listing 2, your database will be located in WASHOME/derby/OpenIdTrustSiteDB.
    Figure 22. Data source wizard - step 3.
    Data source wizard - step 3
  7. Finally, review the summary step and finish the wizard to have the data source created.
    Figure 23. Data source wizard - summary.
    Data source wizard - summary
    Be sure to save your WebSphere configuration after completing the wizard.

Deploy your plug-in

To deploy your plug-in follow these two steps:

  1. Deploy the plug-in jar to the TFIM Runtime by copying the jar file to the <TFIM_install_root>/plugins directory, then publish the plug-ins. This can be done with the console, or with the TFIM command line framework.
    • Using the TFIM Management Console, navigate to Domain Management -> Runtime Node Management and use the Publish Plugins operation to copy the updated plugins directory to the WebSphere configuration repository.
    • Using the command line framework, start wsadmin command line interface to TFIM and execute:
      wsadmin>$AdminTask manageItfimDomain {-operation publishPlugins -fimDomainName <fim_domain_name>}
  2. Configure a runtime custom property to use your trust site manager plug-in. Using the TFIM Management console, navigate to Domain Management -> Runtime Node Management->Runtime custom properties.
    In the Runtime Custom Properties panel add a new property named OpenID.TrustedSitesManagerModuleID and set the value to your module id (jdbctrustedsitesmanager in our example), as was configured in Figure 11. The runtime properties should now look similar to that shown in Figure 24:
    Figure 24. Runtime Custom properties
    Runtime Custom Properties

Testing your custom extension

To test the custom extension, configure the following trace string for diagnostic trace in the WebSphere server where the TFIM Runtime is deployed:

*=info: com.tivoli.am.fim.openid.provider.TrustedSitesManagerFactory=all: com.tivoli.am.fim.demo.openid.*=all

Next, you can attempt to log from a relying party and give an OpenID which will display the consent-to-authenticate screen as shown in Figure 2. After clicking "submit" the information will be stored and you will be able to see the operation in the logs. For example Listing 5 below contains the logs for retrieving the user's trusted sites (for user shane) when retrieving site information from the OpenId trust site manager (refer to Figure 3). Note that due to formatting restrictions, the trace lines have been wrapped. A time and date stamp starts each new trace entry.

Listing 5. Debug Trace Loading and Executing the DemoExtension
[9/10/08 1:30:01:512 EDT] 00000034 TrustedSitesM >
com.tivoli.am.fim.openid.provider.TrustedSitesManagerFactory
getTrustedSitesManager ENTRY
[9/10/08 1:30:01:512 EDT] 00000034 TrustedSitesM >
com.tivoli.am.fim.openid.provider.TrustedSitesManagerFactory
getPreferredModuleId ENTRY
[9/10/08 1:30:01:515 EDT] 00000034 TrustedSitesM <
com.tivoli.am.fim.openid.provider.TrustedSitesManagerFactory
getPreferredModuleId RETURN jdbctrustedsitesmanager
[9/10/08 1:30:01:515 EDT] 00000034 TrustedSitesM >
com.tivoli.am.fim.openid.provider.TrustedSitesManagerFactory
getTSMByModuleID ENTRY jdbctrustedsitesmanager
[9/10/08 1:30:01:521 EDT] 00000034 TrustedSitesM <
com.tivoli.am.fim.openid.provider.TrustedSitesManagerFactory
getTSMByModuleID RETURN success
[9/10/08 1:30:01:521 EDT] 00000034 TrustedSitesM <
com.tivoli.am.fim.openid.provider.TrustedSitesManagerFactory
getTrustedSitesManager RETURN
[9/10/08 1:30:01:521 EDT] 00000034 TrustedSitesM >
com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager.TrustedSitesManagerJDBCImpl
getTrustedSitesForUser ENTRY shane
[9/10/08 1:30:01:522 EDT] 00000034 TrustedSitesM 3
Querying information for user = shane
[9/10/08 1:30:01:522 EDT] 00000034 TrustedSitesM >
com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager.TrustedSitesManagerJDBCImpl
getDBConnection ENTRY
[9/10/08 1:30:01:524 EDT] 00000034 TrustedSitesM <
com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager.TrustedSitesManagerJDBCImpl
getDBConnection RETURN
[9/10/08 1:30:01:524 EDT] 00000034 TrustedSitesM >
com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager.TrustedSitesManagerJDBCImpl
runQuery ENTRY SELECT * FROM USERTOTRUSTSITE WHERE USERNAME = 'shane'
[9/10/08 1:30:01:525 EDT] 00000034 TrustedSitesM <
com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager.TrustedSitesManagerJDBCImpl
runQuery RETURN
[9/10/08 1:30:01:526 EDT] 00000034 TrustedSitesM >
com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager.TrustedSitesManagerJDBCImpl
String2TrustLevel ENTRY PERMIT_ALWAYS
[9/10/08 1:30:01:526 EDT] 00000034 TrustedSitesM <
com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager.TrustedSitesManagerJDBCImpl
String2TrustLevel RETURN PERMIT_ALWAYS
[9/10/08 1:30:01:527 EDT] 00000034 TrustedSitesM >
com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager.TrustedSitesManagerJDBCImpl
String2Attributes ENTRY openid.sreg.email,openid.sreg.nickname
[9/10/08 1:30:01:527 EDT] 00000034 TrustedSitesM <
com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager.TrustedSitesManagerJDBCImpl
String2Attributes RETURN [openid.sreg.email, openid.sreg.nickname]
[9/10/08 1:30:01:527 EDT] 00000034 TrustedSitesM <
com.tivoli.am.fim.demo.openid.jdbctrustedsitesmanager.TrustedSitesManagerJDBCImpl
getTrustedSitesForUser RETURN {
[_username: shane
_trustedSite: https://www.ibmidentitydemo.com/
_trustLevel: PERMIT_ALWAYS
_permitAllOptionalAttrs: false
_permittedOptionalAttrs: openid.sreg.email,openid.sreg.nickname
_userdata: ]}

Following the trace you can see where the TFIM TrustedSitesManagerFactory loads the plug-in identified by jdbctrustedsitesmanager and then invokes the getTrustedSitesForUser method and performs the SQL query to lookup the trusted site information.


Future work

Please note that the JDBC example implementation in this article lacks security as well as optimized performance which can be achieved by using WebSphere connection factories, container persistent management and other J2EE technologies. Storing the database in an industrial strength database like DB2 would also be highly recommended over the Derby flat file database. It is hoped however that IBM customers implementing OpenID Providers might use this example as a starting point for their own persistence mechanisms.


Conclusion

This article has presented the TrustedSitesManager extension point for TFIM 6.2, and outlined two example implementations - a trivial in-memory implementation, and a more meaningful JDBC-based implementation. This article also leveraged TFIM development extensions and demonstrated how to perform calls into the J2EE container from TFIM plug-ins, in this case by using the JndiLookupAction helper class. Information on more of these J2EE container supplied actions can be found in the Advanced Development Considerations section of the TFIM 6.2 STS Module Development Tutorial.


Downloads

DescriptionNameSize
Trusted Site Manager sample implementationscom.tivoli.fim.demo.openid.jdbctrustedsitesmanager_1.0.0.jar11KB
TrustedSitesManagerJDBCImpl.javaTrustedSitesManagerJDBCImpl.java16KB

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), Tivoli, Security
ArticleID=345861
ArticleTitle=Managing OpenID trusted sites with Tivoli Federated Identity Manager
publish-date=10152008