JBoss.orgCommunity Documentation

Chapter 5. Basic Identity Model

5.1. Basic Identity Model
5.2. Managing Users, Groups and Roles
5.2.1. Managing Users
5.2.2. Managing Groups
5.3. Managing Relationships
5.3.1. Built In Relationship Types
5.4. Realms and Tiers

For the sake of convenience, PicketLink provides a basic identity model that consists of a number of core interfaces which define a set of fundamental identity types which might be found in a typical application. The usage of this identity model is entirely optional; for an application with basic security requirements the basic identity model might be more than sufficient, however for a more complex application or application with custom security requirements it may be necessary to create a custom identity model.

The following class diagram shows the classes and interfaces in the org.picketlink.idm.model.basic package:

  • Agent represents a unique entity that may access the services secured by PicketLink. In contrast to a user which represents a human, Agent is intended to represent a third party non-human (i.e. machine to machine) process that may authenticate and interact with your application or services. It declares methods for reading and setting the Agent's login name.

  • User represents a human user that accesses your application and services. In addition to the login name property defined by its parent interface Agent, the User interface declares a number of other methods for managing the user's first name, last name and e-mail address.

  • Group is used to manage collections of identity types. Each Group has a name and an optional parent group.

  • Role is used in various relationship types to designate authority to another identity type to perform various operations within an application. For example, a forum application may define a role called moderator which may be assigned to one or more Users or Groups to indicate that they are authorized to perform moderator functions.

  • Grant relationship represents the assignment of a Role to an identity.

  • GroupMembership relationship represents a User (or Agent) membership within a Group.

  • GroupRole relationship represents the the assignment of a specific Role within a Group to a User or Agent. The reason this relationship extends the GroupMembership relationship is simply so it inherits the getMember() and getGroup() methods - being assigned to a GroupRole does not mean that the User (or Agent) that was assigned the group role also becomes a member of the group.

  • Realm is a partition type, and may be used to store any IdentityType objects (including Agents, Users, Groups or Roles.

  • Tier is a specialized partition type, and may be only used to store Group or Role objects specific to an application.

PicketLink IDM provides a number of basic implementations of the identity model interfaces for convenience, in the org.picketlink.idm.model.basic package. The following sections provide examples that show these implementations in action.

Relationships are used to model typed associations between two or more identities. All concrete relationship types must implement the marker interface org.picketlink.idm.model.Relationship:

The IdentityManager interface provides three standard methods for managing relationships:

  void add(Relationship relationship);

  void update(Relationship relationship);
  void remove(Relationship relationship);
  • The add() method is used to create a new relationship.

  • The update() method is used to update an existing relationship.

    Note

    Please note that the identities that participate in a relationship cannot be updated themselves, however the attribute values of the relationship can be updated. If you absolutely need to modify the identities of a relationship, then delete the relationship and create it again.

  • The remove() method is used to remove an existing relationship.

Note

To search for existing relationships between identity objects, use the Relationship Query API described later in this chapter.

Besides the above methods, IdentityManager also provides a number of convenience methods for managing many of the built-in relationship types. See the next section for more details.

PicketLink provides a number of built-in relationship types, designed to address the most common requirements of a typical application. The following sections describe the built-in relationships and how they are intended to be used. Every built-in relationship type extends the AbstractAttributedType abstract class, which provides the basic methods for setting a unique identifier value and managing a set of attribute values:

What this means in practical terms, is that every single relationship is assigned and can be identified by, a unique identifier value. Also, arbitrary attribute values may be set for all relationship types, which is useful if you require additional metadata or any other type of information to be stored with a relationship.

The GroupMembership and GroupRole relationships are used to represent a user's membership within a Group, and a user's role for a group, respectively.

Note

While the GroupRole relationship type extends GroupMembership, it does not mean that a member of a GroupRole automatically receives GroupMembership membership also - these are two distinct relationship types with different semantics.

A Group is typically used to form logical collections of users. Within an organisation, groups are often used to mirror the organisation's structure. For example, a corporate structure might consist of a sales department, administration, management, etc. This structure can be modelled in PicketLink by creating corresponding groups such as sales, administration, and so forth. Users (who would represent the employees in a corporate structure) may then be assigned group memberships corresponding to their place within the company's organisational structure. For example, an employee who works in the sales department may be assigned to the sales group. Specific application privileges can then be blanket assigned to the sales group, and anyone who is a member of the group is free to access the application's features that require those privileges.

The GroupRole relationship type should be used when it is intended for an identity to perform a specific role for a group, but not be an actual member of the group itself. For example, an administrator of a group of doctors may not be a doctor themselves, but have an administrative role to perform for that group. If the intent is for an individual identity to both be a member of a group and have an assigned role in that group also, then the identity should have both GroupRole and GroupMembership relationships for that group.

Let's start by looking at a simple example - we'll begin by making the assumption that our organization is structured in the following way:

The following code demonstrates how we would create the hypothetical Sales group which is displayed at the head of the above organisational chart:

  Group sales = new Group("Sales");

  identityManager.add(sales);

We can then proceed to create its subgroups:

identityManager.add(new Group("North America", sales);

identityManager.add(new Group("EMEA", sales);
identityManager.add(new Group("Asia", sales);
// and so forth

The second parameter of the Group() constructor is used to specify the group's parent group. This allows us to create a hierarchical group structure, which can be used to mirror either a simple or complex personnel structure of an organisation. Let's now take a look at how we assign users to these groups.

The following code demonstrates how to assign an administrator group role for the Northeast sales group to user jsmith. The administrator group role may be used to grant certain users the privilege to modify permissions and roles for that group:

Role admin = identityManager.getRole("administrator");

User user = identityManager.getUser("jsmith");
Group group = identityManager.getGroup("Northeast");
identityManager.grantGroupRole(user, admin, group);

A group role can be revoked using the revokeGroupRole() method:

identityManager.revokeGroupRole(user, admin, group);

To test whether a user has a particular group role, you can use the hasGroupRole() method:

boolean isUserAGroupAdmin = identityManager.hasGroupRole(user, admin, group);

Next, let's look at some examples of how to work with simple group memberships. The following code demonstrates how we assign sales staff rbrown to the Northeast sales group:

User user = identityManager.getUser("rbrown");

Group group = identityManager.getGroup("Northeast");
identityManager.addToGroup(user, group);

A User may also be a member of more than one Group; there are no built-in limitations on the number of groups that a User may be a member of.

We can use the removeFromGroup() method to remove the same user from the group:

identityManager.removeFromGroup(user, group);

To check whether a user is the member of a group we can use the isMember() method:

boolean isUserAMember = identityManager.isMember(user, group);

Relationships can also be created via the add() method. The following code is equivalent to assigning a group role via the grantGroupRole() method shown above:

Role admin = identityManager.getRole("administrator");

User user = identityManager.getUser("jsmith");
Group group = identityManager.getGroup("Northeast");
GroupRole groupRole = new GroupRole(user, group, admin);
identityManager.add(groupRole);

In terms of API, both the Realm and Tier classes implement the Partition interface, as shown in the following class diagram:

A Realm is used to define a discrete set of users, groups and roles. A typical use case for realms is the segregation of corporate user accounts within a multi-tenant application, although it is not limited this use case only. As all identity management operations must be performed within the context of an active partition, PicketLink defines the concept of a default realm which becomes the active partition if no other partition has been specified.

A Tier is a more restrictive type of partition than a realm, as it only allows groups and roles to be defined (but not users). A Tier may be used to define a set of application-specific groups and roles, which may then be assigned to groups within the same Tier, or to users and groups within a separate Realm.