SeamFramework.orgCommunity Documentation

Chapter 4. Security - Identity Management

4.1. Overview
4.2. Configuring Seam to use Identity Management
4.3. Using the Identity Management Features
4.3.1. Managing Users and Groups
4.3.2. Managing Relationships
4.3.3. Managing Roles
4.4. JpaIdentityStore
4.4.1. Recommended database schema
4.4.2. Configuring JpaIdentityStore
4.4.3. Configuring your Entities

Identity Management is a feature that allows you to manage the users, groups and roles in your application. The Identity Management features in Seam Security are provided by PicketLink IDM. The best place to find more information about PicketLink IDM is the reference documentation, available here.

PicketLink provides two identity store implementations to allow you to use Hibernate or LDAP to store identity-related data (please refer to the PicketLink IDM documentation for details on configuring these). Seam Security provides an additional implementation called JpaIdentityStore, which allows you to store your identity data using JPA.

Note

In a Seam-based application it probably makes more sense to use the standards-based JpaIdentityStore rather than HibernateIdentityStore, as you will most likely be running in an Java EE container that supports JPA.

Like all authentication providers in Seam, Identity Management is supported via a concrete Authenticator implementation called IdmAuthenticator. If you don't provide your own Authenticator implementation then the IdmAuthenticator will be used automatically, however it is also possible (and doesn't hurt) to configure it explicitly. For example, the following XML shows how it would be configured with the Seam Config module:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:s="urn:java:ee" 
   xmlns:security="urn:java:org.jboss.seam.security"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd">

   <security:Identity>
      <s:modifies/>
      <security:authenticatorClass>org.jboss.seam.security.management.IdmAuthenticator</security:authenticator>
   </security:Identity>

Besides configuring the authenticatorClass property, you must also configure the identity store. See the sections later in this chapter to find out how to configure the identity store for your application.

The Identity Management features are provided by a number of manager objects, which can be access from an IdentitySession. The IdentitySession may be injected directly into your beans like so:

import org.picketlink.idm.api.IdentitySession;


public @Model class IdentityAction {
  @Inject IdentitySession identitySession;
  
  // code goes here...
}

Once you have the IdentitySession object, you can use it to perform various identity management operations. You should refer to the PicketLink documentation for a complete description of the available features, however the following sections contain a brief overview.

JpaIdentityStore is an implementation of the PicketLink IdentityStore interface, provided by Seam Security. This identity store allows you to store your identity model inside a relational database, accessible via JPA. It provides an immense amount of flexibility in the way you define your identity model, and in most cases should be compatible with existing database schemas.

Seam provides a configuration bean called JpaIdentityStoreConfiguration, which can be used to configure which entity bean classes will be used by JpaIdentityStore to store identity-related data.

PropertyDescription
identityClassEntity class that contains identity objects such as users and groups
credentialClassEntity class that contains credentials, such as passwords
relationshipClassEntity class that contains relationships between identity objects
roleTypeClassEntity class that contains the names of all role types
attributeClassEntity class that contains additional identity object attributes

The following example shows how JpaIdentityStoreConfiguration may be configured using the Seam Config module:


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns:s="urn:java:ee" 
   xmlns:plidm="urn:java:org.jboss.seam.security.management.picketlink"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd">
      
   <plidm:JpaIdentityStoreConfiguration>
      <s:replaces/>
      <plidm:identityClass>com.acme.model.IdentityObject</plidm:identityClass>
      <plidm:credentialClass>com.acme.model.IdentityObjectCredential</plidm:credentialClass>
      <plidm:relationshipClass>com.acme.model.IdentityObjectRelationship</plidm:relationshipClass>
      <plidm:roleTypeClass>com.acme.model.IdentityRoleName</plidm:roleTypeClass>
      <plidm:attributeClass>com.acme.model.IdentityObjectAttribute</plidm:attributeClass>
   </plidm:JpaIdentityStoreConfiguration>

Seam Security provides a single annotation, IdentityProperty, which can be used to configure your entity beans for use with JpaIdentityStore. This annotation declares two values, value and attributeName:

package org.jboss.seam.security.annotations.management;


public @interface IdentityProperty {
   PropertyType value();
   String attributeName() default "";
}

The value() member is of type PropertyType, which is an enum that defines the following values:

public enum PropertyType {

  NAME, TYPE, VALUE, RELATIONSHIP_FROM, RELATIONSHIP_TO, CREDENTIAL, 
  CREDENTIAL_TYPE, ATTRIBUTE }

By placing the IdentityProperty annotation on various fields of your entity beans, JpaIdentityStore can determine how identity-related data must be stored within your database tables.

In the following sections we'll look at how each of the main entities are configured.

Let's start by looking at identity object. This entity class is configured as the identityClass property of JpaIdentityStoreConfiguration. In the recommended database schema, the IDENTITY_OBJECT table is responsible for storing objects such as users and groups. This table may be represented by the following entity bean:

@Entity

  public class IdentityObject implements Serializable {  
     @Id @GeneratedValue private Long id;
     
     @IdentityProperty(PropertyType.NAME)
     private String name;
     
     @ManyToOne @IdentityProperty(PropertyType.TYPE)
     @JoinColumn(name = "IDENTITY_OBJECT_TYPE_ID")
     private IdentityObjectType type;
     // snip getter and setter methods
  }

In the above code both the name and type fields are annotated with @IdentityProperty. This tells JpaIdentityStore that these two fields are significant in terms of identity management-related state. By annotating the name field with @IdentityProperty(PropertyType.NAME), JpaIdentityStore knows that this field is used to store the name of the identity object. Likewise, the @IdentityProperty(PropertyType.TYPE) annotation on the type field indicates that the value of this field is used to represent the type of identity object.

The IdentityObjectType entity is simply a lookup table containing the names of the valid identity types. The field representing the actual name of the type itself should be annotated with @IdentityProperty(PropertyType.NAME):

@Entity

public class IdentityObjectType implements Serializable {   
   @Id @GeneratedValue private Long id;
   @IdentityProperty(PropertyType.NAME) private String name;        
   
   // snip getter and setter methods
}

The relationship table stores associations between identity objects, and is configured as the relationshipClass property of JpaIdentityStoreConfiguration. Here's an example of an entity bean that has been configured to store identity object relationships:

@Entity

public class IdentityObjectRelationship implements Serializable
{   
   @Id @GeneratedValue private Long id;
   
   @IdentityProperty(PropertyType.NAME)
   private String name;
   
   @ManyToOne @IdentityProperty(PropertyType.TYPE) @JoinColumn(name = "RELATIONSHIP_TYPE_ID")
   private IdentityObjectRelationshipType relationshipType;
   
   @ManyToOne @IdentityProperty(PropertyType.RELATIONSHIP_FROM) @JoinColumn(name = "FROM_IDENTITY_ID")
   private IdentityObject from;
   
   @ManyToOne @IdentityProperty(PropertyType.RELATIONSHIP_TO) @JoinColumn(name = "TO_IDENTITY_ID")
   private IdentityObject to;        
   
   // snip getter and setter methods
}

The name property is annotated with @IdentityProperty(PropertyType.NAME) to indicate that this field contains the name value for named relationships. An example of a named relationship is a role, which uses the name property to store the role type name.

The relationshipType property is annotated with @IdentityProperty(PropertyType.TYPE) to indicate that this field represents the type of relationship. This is typically a value in a lookup table.

The from property is annotated with @IdentityProperty(PropertyType.RELATIONSHIP_FROM) to indicate that this field represents the IdentityObject on the from side of the relationship.

The to property is annotated with @IdentityProperty(PropertyType.RELATIONSHIP_TO) to indicate that this field represents the IdentityObject on the to side of the relationship.

The IdentityObjectRelationshipType entity is a lookup table containing the valid relationship types. The @IdentityProperty(PropertyType.NAME) annotation is used to indicate the field containing the relationship type names:

@Entity

public class IdentityObjectRelationshipType implements Serializable {   
   @Id @GeneratedValue private Long id;
   
   @IdentityProperty(PropertyType.NAME)
   private String name;
   
   // snip getter and setter methods
}