Methods to shift your enterprise.TM  

Enterprise Business Pattern

Identity and Access Management

Provides a means for the users of a system to register their identity and thereby gain access to a system. Their identity and access is managed over time. A user’s identity includes both relevant personal information as well as business related attributes, such as roles and permissions as well as preferences.

identityaccessmanagementsummary

Background

Potential users of a business system must be provided a means of volunteering credentials and other information about themselves in exchange for access to the business resources being offered by the product or services organization. This includes the registration, sign on, access control, and other extended features of identity management.

The registration and sign on features are required to ensure that the user is who they claim to be. Over time the user should be permitted to make necessary changes to their identity. They may need to change contact information and perhaps their password from time to time. The user should be provided a way to sign on to the system if they have forgotten their password. The more emphasis placed on user self service, the less the solution will cost the hosting organization to support their users.

Besides the obvious consumer facing identify management components, there are vital back-office features that protect the system resources that the business offers use of. These are known as access management, and include authorization. A wide variety of resources, such as data and software components may be protected from unauthorized use by applying line-of-business security mechanisms around them.

Value and Benefits

If you want to provide restricted and qualified access to your company’s valued resources, and you want to know something about the persons accessing them, then some degree of Identity and Access Management is clearly a necessity. Providing a centralized service for managing all users of an enterprise application is extremely valuable. Users are those outside and inside your organization, as well as those you consider business partners.

A business’s employees must be able to log on to their own individual workstations and the company’s private network. As the organization grows it will burden a single, centralized identity and access management system. Therefore, one major advantage to enterprise management is, not only centralized control of all users and their access rights, but the ability to push or propagate user identity and access information out to expanding operational and reporting infrastructure on the enterprise and extranet.

Imagine a day in the life of the system administrators in your organization. When a new employee comes on board the administrator must have a workstation pre-configured for their specific job assignment. At many companies system administrators must setup a user account with specific privileges, they must also install a lot of software and configure it per the group or specific job task the individual will work within. There are tremendous benefits to having a centralized identity and access management system that cares for most of the needed account enabling, configuration, and customization.

Now think about your business partners. Companies in some industries have affiliated agents that remotely interact with the hosting organization’s systems. These agents are the sellers of the service or product. There are also the consumers of the service or product that will need to interact with the base organization once the agent has successfully completed their sales task. If you are involved in a similar industry, how will your administrators care for agent accounts without proper identity and access management? Then add to that the management of credentials for the hundreds, thousands, or even millions that will be accessing your site perhaps as a commerce consumer. A centralized, self-service identity management system will virtually eliminate the overhead associated with servicing the variety of system users. Additionally, allowing administrators and managers to provided access control to system resources based on user or job profile, rather than as individuals, will greatly reduce the cost of doing business.

Consider the reality that internal users are running on a Windows platform, while your application and database servers are running on Linux. Practically speaking, all of the heterogeneous computing devices need to access the same centralized identity and access management facilities in order to reduce the complexity of your enterprise.

When you determine to cross the threshold of managing users on both sides of the firewall complexity is raised considerably. Although you may find the challenge quite interesting, you may not be able to justify building an identity and access management solution of the scope and magnitude required by such an extensive vision. On the other hand you may not be able to afford a commercial off-the-shelf (COTS) enterprise identity management product if you are just getting started in your business endeavors. You should measure the value and benefits of quality against the buy versus build tradeoffs before you embark on this task.

Putting It to Work

Designing and implementing your required rendition of identity and access management can be more easily managed by dissecting it into solution pattern strategies, which are distinctly recognizable. For example, the solution pattern strategy for capturing and maintaining the basics of individual, personal identity is called Fundamental Identity (page#), while the individual as a system consumer is defined by the User (page#) pattern. The encapsulating solution pattern strategy that facilitates the user’s voluntary disclosure of personal and user-level information in a self-service fashion is called Registration (page#). The ability to group identities by organizational hierarchy is defined by Identity Grouping (page#). The authentication of a user that is logging in to use the system is called Sign On (page#). The configuration of various line-of-business responsibilities is embodied in the Role (page#) solution pattern strategy. The roles of usage are mapped to various system resources, such as data and executable software components, via the Security Policy (page #) pattern. Exactly how it is determined whether a user will be granted access to a given system resource is embodied in the Access Authorization (page #) pattern. Consider the use of these and other strategies as we put the Identity and Access Management pattern to work.

Information and Structure

When approaching an Identity and Access Management solution, no matter what backing third-party tools you use, you must first identify your users and organizational groupings, the information you will collect about them, and how you will control their access to system resources. This information will depend on the kind of system you are implementing. The dataset may be quite simplistic or moderately complex, but will generally be about persons, or systems, or both. Let’s consider two examples, each of which is at the opposite ends of the complexity and usability spectrum.

Your company provides a free tool to help developers. You’d like to have some idea of how many people are using your tool and who they are. So in exchange for downloading they must tell you their name and their email address. You promise to inform your tool’s users when there are updates, which you can fulfill because you have their email address. Further, since you have their name you can address them in a courteous way, such as “Dear Toni,” in the email body. You’ll use her email address as a unique identifier.

Clearly your fundamental user data is very basic. Here’s an idea of what a user identity tree might look like in plain-text format, along with a domain object representation:

person

people
  person
    person-info
      emailAddress (unique-1)
      firstName
      lastName
  . . .
  person
    person-info
      emailAddress (unique-N)
      . . .

Now let’s consider the other end of the spectrum. Your company functions with the full complement of enterprise business patterns: Business to Consumer, Business to Business, and Business to Enterprise. This fact alone requires more primary branch nodes on the Identity Grouping (page#) tree, for example:

customers
  . . .
employees
  . . .
partners
  . . .
people
  . . .

The people branch is still useful. It is where you will keep all information regarding the people your system knows about. Additionally, you will also want to create contexts, similar to groups, which distinguish the people you know about as customers, employees, or partners.

Besides having a more complex tree, you also want to collect much more detailed information for each kind of identity. For employees you need to know both business information and some degree of personal information. At a minimum you must know the pager and cell phone numbers of system admin personnel, for example. Collecting both business and personal information implies the probability of having more than one set of contacts for each employee.

Your partners will probably be grouped under business entities, and you may want to categorize each partner’s identities by resource and departmental groups, such as systems, accounting, and inventory. Partner system identities have names and descriptions. A partner’s accounting and inventory groups will include a number of staffers who will interact with your back-office systems through a Dynamic Web Site (page #).

You will also collect information about the external users (non-employees, non-partners) of the system (e.g. your customers). While you probably want to know the external user’s name and email address, it’s also likely that you’ll want to capture the company they represent and other common, primary contact information for them.

You could attempt to obtain nearly as much information about external users as you do employees, but for most systems this is neither necessary nor practical. Depending on the line of business you are conducting it may not be proper or legal to probe for such data (minor children, for example). It will require a delicate balance to avoid overwhelming users by prompting them for too much information during registration. One worthy strategy is to obtain only very basic information at initial registration (email address, personal name, user name, and password), and then gather more at points when you absolutely need it (shipping address, date of birth, and gender).

Based on these requirements your identity tree might have the following logical composition:

customers
  person
    username (unique-ID)
      firstName
      lastName
      companyName
      jobTitle
      contactInfo
        emailAddress
        postalAddress
        telephoneNumber
  . . .

employees
  departmentName
    manager (person)
    person
      username (unique-ID)
        firstName
        middleName
        lastName
        maidenName
        jobTitle
        uniquePersonIdentifier (e.g. SSN)
        dateOfBirth
        contactInfo
          emailAddress[]
          postalAddress[]
          telephoneNumber[]
    . . .

partners
  companyName
    primaryContact (person)
    departmentName
      primaryContact (person)
      person
        username (unique-ID)
        firstName
        lastName
        jobTitle
        contactInfo
          emailAddress
          postalAddress
          telephoneNumber
      . . .
      system
        username (unique-ID)
        description
        location
  . . .

people
  username (unique-ID, 1)
    password
    pin
    hint
  . . .
  username (unique-ID, N)
    password
    pin
    hint

The people context, providing a common set of all system users, is key because every other major context (customers, employees, and partners) relies on usernames and passwords to obtain access to the system. It is only after a user has signed on to the system that it is important to know who they are and what they can do. Even partner back-office systems access your B2B back-office systems via username and password. As you will see, the User (page #) pattern is the essential bootstrap for supporting the link between the Fundamental Identity (page #) and User Account (page #) pattern (and others). While users have authentication credentials and identities they also have accounts, roles, and other characteristics.

The relationships presented above form the basis of a static domain model structure. The exact information that you collect will be determined by your own analysis. For example, your partners might not access your systems via services. In the case of a manufacturer, for example, a partner might be a wholesaler, and you may also have some relationships with retails with which you act as the wholesaler. So your partner node may have people (perhaps not within separate departments) but not systems, and they will likely access your systems via a web GUI very similarly to B2C customers. Unless they support supply chain management, a manufacturer may not need to provide back-office services. However, you will still want more information about such partners than you would know about typical B2C customers.

Detailed analysis notwithstanding, the information structure presented above is more or less suitable for many businesses. Detailed UML diagram are provided in relevant solution patterns, providing further clarity to the textual rendition of the above identity tree. Note, however, that how you implement your identity and access persistence mechanism will determine the physical structure of the logical layout presented above.

Technology Considerations

The backing technology you end up using may be dictated for you. Organizations that have been managing users as described by this pattern will have had some form of identity and access management infrastructure in place for some time. If corporate direction mandates that existing infrastructure continue to be used, and that infrastructure is not a directory service, then much of this section will be purely academic for you.

However, in the rare case where you are able to start from scratch, or in the not so rare case where part of your mission is to replace existing identity and access management infrastructure, I highly recommend that you consider the use of a directory service. While it is out of the scope of this book to provide exhaustive coverage of directory services, suffice it to say that directory services are tailor made to deal with identity and access management. Much of identity and access management’s core feature definition is a standard, out-of-the-box feature of directory services. Such standard features include highly efficient hierarchical tree structures that are tuned for quick searching, customizable type and attribute capabilities, and identity replication, which will allow you to propagate your identity structure as your needs grow. Using a directory service with such built-in features will save you many hours of implementation, testing, and deployment time. Just the area of identity replication alone could require many person months of design and development that can be sidestepped by obtaining a commercial or open source directory service.

The most widely used kind of directory service uses LDAP, or Lightweight Directory Access Protocol. My examples use OpenLDAP specifically. Again, it is out of the scope of this book to provide an extensive treatment of LDAP. Therefore I assume that you are already familiar with or will familiarize yourself with LDAP. An excellent Web site supporting LDAP documentation is http://ldap.akbkhome.com/. Clayton Donley has produced a practical guide to LDAP programming [LDAP-PMI]. I believe these are useful reference works and guides.

However, none of these suggestions indicate that the use of a relational database is out of the question for use as an identity and access management system. You may lose some advantages that a directory service provides, but most directory services are backed by some kind of database anyway. For example, OpenLDAP uses the Berkeley Sleepy Cat Database as its backing persistence mechanism.

Architectural and Design Decisions

The following diagram illustrate some possible architectural and design direction from a component model perspective:

architecture

The diagram shows the major architectural concerns. For example, IdentityManager is the Remote Façade [P of EAA] through which clients gain access. The User and Person components are of the domain objects involved. The DirectoryService component is the platform specific access to LDAP, namely JNDI or ??? [.NET API…]. Since the LDAP or database server is at least logically (and most likely physically) on a separate tier—generically called the data integration tier—the component diagram shows that separation by placing it in a separate package.

When storing identity and access data in LDAP you use an object class to specify what you are storing. Listed here in class hierarchical order are a few of the more obvious LDAP object classes that might be suitable for storing our person identity data. Note that these are standard LDAP classes available with most directory implementations:

person
  organizationalPerson
    inetOrgPerson
  residentialPerson

I will be using both standard and custom object classes in my examples. For details on standard ones, see http://ldap.akbkhome.com/objectclasstree.html, an online LDAP Schema Viewer. The person object class is the most basic, and therefore the most limited. Only a few attributes are supported, and certainly not enough to support some moderately complex identity management requirements. There are only a unique name, password, and telephone number. The organizationalPerson object class extends person, and introduces a more complete set of attributes, but it still fails to provide the richest identity management option. We must navigate two subclasses below person before we find the inetOrgPerson object class, one that is suitable for my examples, but may be somewhat limited for many businesses.

There are two possible issues with inetOrgPerson. First, it is not always standard in all directory services, including the servers I reference below, namely OpenLDAP and ActiveDirectory. This proved not to be a serious issue as both servers provide inetOrgPerson as an add-on schema. If it is not available for your server perhaps you may add it in yourself, or your LDAP server may provide a similar or better object class.

The second potential issue is that inetOrgPerson may not be rich enough for your production implementation. If this is the case you could easily extend it, or create a completely unique object class that has much richer set of attributes. That should be the least of your problems. The point of my selection is, at least you will be able to glean the general ideas behind the pattern by studying my examples and use of inetOrgPerson.

Solution Pattern Strategies

The following are the primary solution patterns strategies for the Identity and Access Management EBP. The strategies are presented in more or less logical order.

Registration

Registration (page#) allows the potential user of a system to volunteer credentials and other information about themselves in exchange for granted access to all or part of the system. System access may be automatically granted when the user submits their registration information, or the system provider may require some approval process to be managed by a set of business workflow tasks.

Likely the sensitivity of information and/or the value of resources being offered by the system will dictate the level of approval enforced. Of course, in many cases the business would do well not to make the registration and (optional) approval process so strict that it discourages new users from completing their access request or returning to the system for future use. (I have seen this happen.)

A simple strategy to ensure that you at least verify the user’s valid email address is to send a confirmation of registration email message to the user’s registered address that requires their confirmation reply before registration is completed. The Registration (page#) solution pattern deals with the user interface portion of the Identity and Access Management pattern, while it relies on the Fundamental Identity (page#) solution pattern to define what user information gets collected. While this pattern will most often be a self-service facility, it may also be an administrative facility since system administrators may need to setup default user accounts in behalf of new employees and partners.

User

User (page#) provides the structure behind persisting the user’s credentials that are entered via Registration (page#). Sign On (page#) also uses it to authenticate a user that is attempting to access the system. This pattern may provide additional authentication credentials, such as a PIN. Further, if the user loses their password or other authentication principal information, Sign On (page#) can use this pattern to provide a recovery scheme for the user.

Fundamental Identity

Fundamental Identity (page#) is the solution pattern strategy that defines the structure of and facilitates the storage and retrieval of registration information. It focuses on what kind of information the registration process must collect, and provides a standard API for accessing and updating the data once it has been stored. It is used by the Registration (page#) pattern to determine what data is collected about each user.

Sign On

Sign On (page#) solution-pattern strategy defines how the registered user submits their credentials in order to gain access to the system’s resources. It also encapsulates how the user terminates their session by signing off. While this pattern seems simple enough, examining the details of the pattern will reveal some conveniences that make the user experience more pleasant in the case where credentials are forgotten. The approach of Single Sign On (SSO) is a strategy provided by this pattern.

Identity Grouping

The Identity Grouping (page #) pattern maintains a set of unique members that can be granted common characteristics such as access-based roles. A group may contain users and one or more other groups (nested groups, or groups within groups). Basically groups have the benefit of defining additional identity and allowing roles and other possible characteristics to be more efficiently granted across a broad range of users.

Role

Role (page#) facilitates a means for the business to grant levels of access and responsibility to each user according to the level of trust recognition. Such access levels and responsibilities are often referred to as permissions or privileges. Often times extended access and special responsibility definition may be required only for internal users, while a very limited set of access rights is implied toward external users (such as through a default “guest” grant). Note that the Role (page#) pattern focuses on line-of-business access control. Thus, users and groups do not have permissions/privileges per se. They are only granted permissions by being in a role that has the permissions/privileges to access a given system resource.

Roles also may be dynamic; that is, a user may qualify as being in a role because of meeting some special dynamic criteria. The dynamic criteria may be based on the time of day, the day of the month, time of year, according to the amount of money spent, and so forth.

Security Policy

Security Policy (page #) maps access to system resources from the specific resource to the Role (page #) that the requester must play to access it. Such policies may be very simple, or complex depending on the nature of the platform and environment that it supports. In essence policies serve as the grant of permissions on system resources.

Access Authorization

Can a given user access a specific system resource at a moment in time? The Access Authorization (page #) pattern uses Role (page #) definitions to determine whether or not a user will be granted access to such as resource when they attempt it. But the required Role (page #) is found by looking at the resource’s assigned Security Policy (page #).

Examples

All reference implementation details for the Identity and Access Management are provided in the underlying solution patterns. I supply some key supporting code and configuration examples here that are consumed by the solution patterns. The static structure of a simple framework is depicted in the following class diagram:

staticstructure

Class DirectorySession is used to initiate the persistence and retrieval of all directory-based domain objects:

package com.jubatus.business.service.directory;

import com.jubatus.business.domain.DirectoryDomainObjectIF;

public class DirectorySession implements DirectorySessionIF {
  
  public static DirectorySessionIF getInstance() {
    return new DirectorySession();
  }
  
  public Object read(DirectoryDomainObjectIF anObject) throws DirectoryException {
    return anObject.getDirectorySession().read(anObject);
  }
  
  public void save(DirectoryDomainObjectIF anObject) throws DirectoryException {
    anObject.getDirectorySession().save(anObject);
  }
  
  public void setParentContext(String aContext) {
    // unused
  }
  
  public void update(DirectoryDomainObjectIF anObject) throws DirectoryException {
    anObject.getDirectorySession().update(anObject);
  }
}

When a component such as the IdentityManager Remote Façade saves a new User to the directory service, it would do so in the following manner:

UserIF tempUser = . . .
DirectorySessionIF tempSession = DirectorySession.getInstance();
tempSession.save(tempUser);

As you can see from the save() method the common DirectorySession simply dispatches the persistence request onto the directory domain object’s own DirectorySessionIF implementation. Therefore, every directory domain object must implement the DirectoryDomainObjectIF interface:

package com.jubatus.business.domain;

import java.io.Serializable;

import com.jubatus.business.service.directory.DirectorySessionIF;

public interface DirectoryDomainObjectIF extends Serializable {

  public DirectorySessionIF getDirectorySession();
}

Example implementers as seen in the diagram are UserDirectorySession and PersonDirectorySession. These classes are included in the User (page #) and Fundamental Identity (page #) patterns, respectively.

The responsibility of the implementing directory domain object (such as User and Person) is to answer its own specific implementation of DirectorySessionIF. Every directory-based domain object uses interface DirectorySessionIF to actually control its own persistence details:

package com.jubatus.business.service.directory;

import com.jubatus.business.domain.DirectoryDomainObjectIF;

public interface DirectorySessionIF {

  public Object read(DirectoryDomainObjectIF anObject) throws DirectoryException;
  public void save(DirectoryDomainObjectIF anObject) throws DirectoryException;
  public void setParentContext(String aContext);
  public void update(DirectoryDomainObjectIF anObject) throws DirectoryException;
}

When the common DirectorySession dispatches the persistence request on to the directory domain object’s DirectorySessionIF, that implementation is responsible for interacting with the directory service. There is a helper class use by the domain objects. It is the class DirectoryService. My examples use Java and its JNDI API, so the DirectoryService component provides some basic utility that is common to all directory domain objects in my examples:

package com.jubatus.business.service.directory;

import java.util.Properties;

import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.BasicAttribute;
import javax.naming.directory.DirContext;
import javax.naming.directory.InitialDirContext;
import javax.naming.directory.ModificationItem;

public class DirectoryService {

  // some of these should be properties or managed dynamically via JMX
  private static final String BASE_DOMAIN_NAMING_CONTEXT = "dc=jubatus,dc=com";
  private static final String COMMON_NAME = "cn";
  private static final String DEFAULT_HOST = "localhost";
  private static final String DEFAULT_PORT = "389";
  private static final String DEFAULT_ROOT_DN = "cn=admin," + BASE_DOMAIN_NAMING_CONTEXT;
  private static final String DEFAULT_ROOT_PASSWORD = "secret";
  private static final String EBP_USER_ACCOUNT = "ebpUserAccount";
  private static final String GROUP_OBJECT_CLASS = "posixGroup";
  private static final String GROUP_OF_UNIQUE_NAMES_OBJECT_CLASS = "groupOfUniqueNames";
  private static final String GROUPS_CONTEXT = "ou=groups";
  private static final String INET_ORG_PERSON_OBJECT_CLASS = "inetOrgPerson";
  private static final String MEMBERS = "members";
  private static final String OBJECT_CLASS = "objectClass";
  private static final String ORG_PERSON_OBJECT_CLASS = "organizationalPerson";
  private static final String PEOPLE_CONTEXT = "ou=people,";
  private static final String PERSON_OBJECT_CLASS = "person";
  private static final String TOP_OBJECT_CLASS = "top";
  private static final String UID = "uid";
  
  private DirContext dirContext;
  
  public static DirectoryService getInstance() {
    return new DirectoryService();
  }
  
  public void createSubcontext(String aContext, Attributes anAttrs) throws DirectoryException {
    try {
      this.getDirContext().createSubcontext(aContext, anAttrs);
    } catch (NamingException e) {
      e.printStackTrace();
      throw new DirectoryException("Naming exception", e);
    }
  }
  
  public String getDomainNamingContext() {
    return BASE_DOMAIN_NAMING_CONTEXT;
  }
  
  public String getGroupContext(String aGroupName) {
    return COMMON_NAME + "=" + aGroupName + "," + this.getGroupsContext();
  }
  
  public String getGroupsContext() {
    return GROUPS_CONTEXT + "," + this.getDomainNamingContext();
  }
  
  public String getGroupMembersContext(String aGroupName) {
    return COMMON_NAME + "=" + MEMBERS + "," + this.getGroupContext(aGroupName);
  }
  
  public Attribute getGroupMembersObjectClasses() {
    Attribute tempAnswer = new BasicAttribute(OBJECT_CLASS);
    tempAnswer.add(TOP_OBJECT_CLASS);
    tempAnswer.add(GROUP_OF_UNIQUE_NAMES_OBJECT_CLASS);
    return tempAnswer;
  }
  
  public Attribute getGroupObjectClasses() {
    Attribute tempAnswer = new BasicAttribute(OBJECT_CLASS);
    tempAnswer.add(TOP_OBJECT_CLASS);
    tempAnswer.add(GROUP_OBJECT_CLASS);
    return tempAnswer;
  }
  
  public String getPeopleContext() {
    return PEOPLE_CONTEXT + this.getDomainNamingContext();
  }
  
  public String getPersonContext(String aUserAccountContext, String aCn) {
    return COMMON_NAME + "=" + aCn + "," + aUserAccountContext;
  }
  
  public Attribute getPersonObjectClasses() {
    Attribute tempAnswer = new BasicAttribute(OBJECT_CLASS);
    tempAnswer.add(TOP_OBJECT_CLASS);
    tempAnswer.add(PERSON_OBJECT_CLASS);
    tempAnswer.add(ORG_PERSON_OBJECT_CLASS);
    tempAnswer.add(INET_ORG_PERSON_OBJECT_CLASS);
    return tempAnswer;
  }
  
  public String getUserAccountContext(String aUsername) {
    return UID + "=" + aUsername + "," + this.getPeopleContext();
  }
  
  public Attribute getUserAccountObjectClasses() {
    Attribute tempAnswer = new BasicAttribute(OBJECT_CLASS);
    tempAnswer.add(TOP_OBJECT_CLASS);
    tempAnswer.add(EBP_USER_ACCOUNT);
    return tempAnswer;
  }
  
  protected DirContext getDirContext() throws NamingException {
    
    if (dirContext == null) {
      Properties tempEnv = new Properties();
      
      tempEnv.put(
            DirContext.INITIAL_CONTEXT_FACTORY,                     
            "com.sun.jndi.ldap.LdapCtxFactory");
      tempEnv.put(
          DirContext.PROVIDER_URL,
          "ldap://" + DEFAULT_HOST + ":" + DEFAULT_PORT);
      tempEnv.put(
          DirContext.SECURITY_AUTHENTICATION,
          "simple");
      tempEnv.put(
          DirContext.SECURITY_PRINCIPAL,
          DEFAULT_ROOT_DN);
      tempEnv.put(
          DirContext.SECURITY_CREDENTIALS,
          DEFAULT_ROOT_PASSWORD);
      
      dirContext = new InitialDirContext(tempEnv);             
    }
    
    return dirContext;
  }
  
  public void modifyAttributes(String aContext, ModificationItem[] aModsArray)
      throws DirectoryException {
    try {
      this.getDirContext().modifyAttributes(aContext, aModsArray);
    } catch (NamingException e) {
      e.printStackTrace();
      throw new DirectoryException("Naming exception", e);
    }
  }
  
  private DirectoryService() {
    super();
  }
}

Consequences

You will find tradeoffs among the following competing forces within the Identity Management business pattern.

  • Potential for True Reuse: Since you are taking the time to think things through on a topic that many dismiss as rudimentary or a complete nuisance, you may be able to ensure that your organization never has a competing, incomplete, or dead-end user registration and sign on facility. True, each application that your organization develops will have its own special configuration and user preferences requirements, but need they all have their own unique way of managing user identity, authentication, and authorization? Hopefully not. If your organization is not already out of control—perhaps politically hamstrung, as I have seen before on this very topic—on this front, make every reasonable effort now to ensure the reuse of this essential, critical, part of every serious enterprise application.

  • Keep It Simple: For the most basic of Web-based enterprise applications supporting a single database table for user credentials and another for preferences, may be all that is really needed. This is especially the case if you have very limited timeframes for development and you just can’t introduce another complexity. In this case avoiding a top-shelf identity management solution may be in your best interests. Of course you will still need to support registration and sign on, and you may want to provide facilities for users to configure simple preferences. But you will probably want to avoid going down the path of a full-featured Role (pg#) or Identity Propagation (pg#) strategies. As previously stated, buy versus build are options you will have to study carefully. In many cases buying will contribute more toward simplicity than building your own identity management solution, especially if “full-featured” is part of your checklist.

  • Make It Complete and Robust: This is the exact opposite competing force to Keep It Simple. I argued sufficiently under the Value and Benefits section for many of the reasons that you will want to invest in this pattern to the fullest extent. Insert all those arguments and more (it is outside the scope of this book to discuss every advance to using a directory service) here, which will heavily weight your decision toward implementing a full-featured, enterprise, extensible, and scalable identity management system.

  • Involve Everyone: Similar to the reasoning behind the Keep It Simple consequence, there is the tradeoff of having to involve a lot of your IT staff in order to provide an extensible identity management solution. There’s far more involved than a software developer simply accessing an API from your enterprise application (such as accessing JNDI from Enterprise JavaBeans, or ActiveDirectory from COM objects). You must give careful consideration to the directory service selection, buy versus build, how your selection should be deployed, and how it will expand in the future. This is likely going to involve executive management (at least your CIO and/or CTO) as well as network and application architects, and the system administrators who are going to have to support it from cradle to grave. Of course the requirements of the business users must absolutely be met. Be prepared for some churn and heartache before anything useful gets accomplished.

Related Patterns

The following are the solution patterns that may be used in conjunction with the solution patterns key to the Identity and Access Management pattern.

  • User Account (page #): Whenever a business system user can make purchases, there must be a user account associated with the user identity. While user identity manages the basics of who’s who, the user account manages the details about transactions that the user has made or will make.

Frameworks and Tools

  • Products and Frameworks: See products such as Netegrity’s IdentityMinder and SiteMinder, IBM’s Tivoli Identity Management, Sun ONE Directory Server, Sun Java™ System Identity Manager, RSA’s ClearTrust, and Microsoft’s Access Manager. Many COTS products can be used as near-turnkey and custom solution platforms.

  • Tools: The sub-pattern strategies above make use of freely and commercially available tools such as OpenLDAP and ActiveDirectory for storing and retrieving user identity and related information. In addition our recommended suite of tools, including Tomcat and JBoss are used in my example solutions.