Red Hat

In Relation To PicketLink

In Relation To PicketLink

Securing Your Applications with PicketLink and DeltaSpike

Posted by    |       |    Tagged as CDI PicketLink

If you’re looking for a simple way to secure your Java EE application’s classes and methods, then PicketLink in conjunction with DeltaSpike provides an elegant and flexible solution thanks to DeltaSpike’s support for typesafe security annotations. This powerful combination means you can easily apply security to your application in three simple steps, which we’ll be examining in more detail in this article.

Before we get started though, let’s take a closer look at each of these individual projects.

PicketLink

PicketLink (http://www.picketlink.org) is an application security framework for Java EE. It provides features such as Identity Management (IDM), credential management, authentication API, permissions and permission management, plus much more. At the time of writing, the latest available version of PicketLink is 2.6.0.Final.

Apache DeltaSpike

Apache DeltaSpike (http://deltaspike.apache.org) is a collection of portable extensions for Java EE, built on top of the CDI (Contexts and Dependency Injection) standard. It enhances the Java EE platform by providing a set of useful features for application developers. The latest release of Deltaspike is 1.0.

Setting up the Maven Dependencies

This step is required to add the PicketLink libraries to your application. Start by defining a property value for the version of PicketLink that you’ll be using - the latest version at time of writing is 2.6.0.Final. Add the following property declaration to the <properties> section of your project’s pom.xml:

  <properties>
    <!-- PicketLink dependency versions -->
    <version.picketlink.javaee.bom>2.6.0.Final</version.picketlink.javaee.bom>
  </properties>

Then add the PicketLink BOM to the <dependencyManagement> section:

  <dependencyManagement>
    <dependencies>
      <!-- Dependency Management for PicketLink and Apache Deltaspike. -->
      <dependency>
        <groupId>org.picketlink</groupId>
        <artifactId>picketlink-javaee-6.0</artifactId>
        <version>${version.picketlink.javaee.bom}</version>
        <scope>import</scope>
        <type>pom</type>
      </dependency>
    </dependencies>
  </dependencyManagement>

Finally, add the PicketLink dependency to the <dependencies> section:

    <dependency>
      <groupId>org.picketlink</groupId>
      <artifactId>picketlink</artifactId>
      <scope>compile</scope>
    </dependency>

We’re done! The next step is to enable the DeltaSpike security interceptor.

Enabling the Security Interceptor

For the security interceptor to perform authorization checks for the classes or methods that we wish to secure with our security binding annotations, we must first enable it in our application’s beans.xml file. In a web application this file can be found in the WEB-INF directory. Add the <interceptors> section as shown in the following example:

<beans xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="
      http://java.sun.com/xml/ns/javaee 
      http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
    <interceptors>
        <class>org.apache.deltaspike.security.impl.extension.SecurityInterceptor</class>
    </interceptors>
</beans>

Step 1: Create the Security Annotation

This first step is extremely simple - all we need to do is create an annotation and meta-annotate it with @SecurityBindingType. As an example let’s create a security annotation that we can use to restrict access only to users that are currently logged in:

@Retention(value = RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@SecurityBindingType
public @interface LoggedIn { }

Make sure that the @Target is set to both TYPE and METHOD - this will ensure that the annotation can be used to secure either all the methods of a class (when applied to the class itself) or to secure individual methods. The @SecurityBindingType annotation can be found in the org.apache.deltaspike.security.api.authorization package.

Step 2: Create the Authorizer method

This step is where we’ll be implementing the business logic for our security annotation. Each security binding annotation requires a corresponding authorizer method. This method must match the security binding annotation and any of its member values (excluding those annotated with @NonBinding, mirroring the behaviour of CDI itself). There must be exactly one authorizer method per unique security binding annotation usage.

The authorizer method can be placed in a bean class of your choosing, and there are no restrictions on the scope of the bean (in the following example we’ll use an @ApplicationScoped bean). Besides the security binding annotations, the authorizer method must also be annotated with @Secures, to denote that the method is being used to secure that security binding type:

@ApplicationScoped
public class Authorizer {
    @Secures
    @LoggedIn
    public boolean isLoggedIn(InvocationContext invocationContext, Identity identity) {
        return identity.isLoggedIn();
    }
}

The parameters of the authorizer method are treated as injection points (except for parameters of type InvocationContext which may be used to inspect metadata pertaining to the method from which the security check is being invoked). In the above example, we inject the Identity bean which represents the currently authenticated user - the Identity bean provides a method called isLoggedIn() that allows us to check if the current user is logged in.

Step 3: Apply the annotation to your methods

By the time we reach this step all of the hard work has been already done. The only remaining task is to apply the new security binding annotation to the methods and/or classes that you wish to secure. Let’s start off with a really simple example:

@RequestScoped
public class PostController {
    @LoggedIn
    public void getNewPosts() {
        // business logic here
    }
}

In this code we’ve applied our @LoggedIn security binding annotation to the getNewPosts() method of a request-scoped bean called PostController. When the user invokes this method, the security interceptor will intercept the method call and invoke the authorizer method to determine if the currently authenticated user is logged in. If the authorizer method returns true then the method invocation will then proceed as normal, otherwise an AuthorizationException will be thrown. If we would like to apply the same security restriction to all of the methods of a bean, we can put the annotation on the bean class instead:

@LoggedIn
@RequestScoped
public class PostController {
    public void getNewPosts() {
        // business logic here
    }
}

A Complete Example

You can find a complete example of using PicketLink with DeltaSpike in the following quickstart project:

https://github.com/jboss-developer/jboss-picketlink-quickstarts/tree/master/picketlink-deltaspike-authorization

Summary

In this article we examined how we can get the most out of DeltaSpike’s security annotation feature by combining it with a powerful security framework such as PicketLink. By following three simple steps we learned how to define a new security annotation, implement its business logic and then apply it to the methods and classes which we wish to protect.

PicketLink Deep Dive - Part 2

Posted by    |       |    Tagged as Java EE PicketLink

Welcome to part 2 of the PicketLink Deep Dive series. In case you missed part 1, you can find it here. In part 1 you’ll also find links to helpful resources, such as the PicketLink documentation, distribution binaries, source code and more.

In this issue, we’re going to be taking a closer look at PicketLink’s support for partitions. Let’s start though by establishing what exactly partitions are in the scope of PicketLink and how they are used.

What is a Partition?

In the simplest definition, partitions in PicketLink are used to segregate identities (such as users, groups and roles) from each other. Why would you want to do this, you wonder? Well one common use case for such a feature would be for an application that serves multiple clients/companies, with each client having its own distinct set of user accounts. Another use case might be when you wish to use PicketLink as an IDP (Identity Provider) that services multiple applications, with each application having a distinct set of identities. Whenever you need to support the creation of distinct “sets” of users or other identity types, partitions are there to help you.

Do I need to use them?

If your application has simple security requirements, such as a single set of user accounts and maybe perhaps a few groups and roles, then you probably don’t need to use PicketLink’s extended support for partitions. The good news is that you don’t really need to do anything special - simply ignore the partition aspect of PicketLink and it shouldn’t ever bother you! (You can probably also skip the rest of this article if you like and just come back for part 3).

Partitions and the Identity Model

If you read part 1, you may remember how the identity model was described and how each identity object implements the IdentityType interface, as shown in this class diagram:

What we didn’t explain in part 1 was how every IdentityType object must belong to a Partition. This means that every user, group, role, agent, account (or any other identity type) always has a partition object, and its getPartition() method will always return this object (and never null). If you’ve worked with the PicketLink API already you may have noticed these overloaded methods on the PartitionManager interface:

    IdentityManager createIdentityManager() throws IdentityManagementException;
    IdentityManager createIdentityManager(Partition partition) throws IdentityManagementException;

At first glance it might seem that the first of these methods might return a “partitionless” IdentityManager instance, however behind the scenes PicketLink actually returns an IdentityManager for the default partition. We’ll examine this in more detail shortly, but first let’s look at how PicketLink supports different partition types.

Creating a custom partition type

Since the Partition interface cannot be instantiated itself, it is generally up to the developer to provide a concrete partition implementation. PicketLink provides two built-in partition types which you are free to use (see the next section for details), but otherwise it is very simple to create your own partition type. The AbstractPartition abstract base class makes this easy by doing most of the work for us, and may be easily extended to create a custom partition type. Let’s take a look at a really simple example:

@IdentityPartition(supportedTypes = {IdentityType.class})
public class Organization extends AbstractPartition {
    public Organization() {
        super(null);
    }
    public Organization(String name) {
        super(name);
    }
}

That’s all the code we need! We can use this new Organization partition type to create identities within separate Organizations. The only really significant feature worth a special mention in the above code is the @IdentityPartition annotation. This annotation tells PicketLink that the class is a partition class, and also that it allows the storing of all IdentityType types (including any subclasses of IdentityType). If we only wanted to store User objects in the partition then we could instead annotate the class like this:

@IdentityPartition(supportedTypes = {User.class})

It’s also possible to “trim” support for certain identity classes off the hierarchy tree, by specifying them in the unsupportedTypes member. For example, let’s say that we wish to be able to store all identity types in an Organization, except for Roles. The annotation would now look like this:

@IdentityPartition(supportedTypes = {IdentityType.class}, unsupportedTypes = {Role.class})

Finally, since the Partition interface extends AttributedType, we know that it will have a unique identifier and that we are able to also assign it arbitrary attribute values, so with our new Organization partition we can do stuff like this:

Organization org = new Organization(acme);
org.setAttribute(new Attribute<String>(description, Manufactures anvils and other failure-prone devices);
partitionManager.add(org);
log.info(Created new Organization partition with id:  + org.getId());

Built In Partition Types

PicketLink provides two built-in, optional partition types - Realm and Tier. Both of these classes can be found in the org.picketlink.idm.model.basic package along with the other classes that form the basic identity model. Both of these partition types are provided for convenience only, there is absolutely no requirement that you use either of them. If you do wish to use these built-in partition types, then here are our guidelines (which you may choose to ignore if you wish):

Realm

The Realm partition type is analogous to the commonly accepted definition of a security realm and is recommended for use when you need to create a distinct set of users, groups and roles (or other identity types) for restricting access to an application. It supports all identity types.

Tier

A Tier is designed to be used in conjunction with a Realm and is intended for storing only roles or groups (or any other non-Account identity type, i.e. an identity type that isn’t capable of authenticating such as a User) while the Realm stores the Users. It is intended for storing tier-specific identities; for example if your application consists of multiple tiers, then each tier can define its own set of roles which in turn may be assigned certain tier-specific privileges. This way, a user in a separate Realm can be easily assigned one or more Tier-specific roles to give them access to the services provided by that tier.

The Default Partition

As mentioned above, Identity Management operations performed on an IdentityManager returned by the PartitionManager.createIdentityManager() method are actually done in the default partition. This default partition is actually a Realm object with a name of “DEFAULT”. If your PicketLink environment isn’t configured to support partitions then it doesn’t matter, PicketLink will transparently handle the support for the default partition without you having to do anything special.

Partitions and Relationships

So far we haven’t mentioned where identity relationships fit into the picture in regards to partitions. By their very nature, relationships differ from identities in that they don’t belong to a specific partition. If you think about this, it makes quite a lot of sense as a relationship is a typed association between two or more identities and those identities may not all exist within the same partition. For example, based on the description of the Realm and Tier partitions above we know that it is possible to have a Role that exists in a Tier, granted (via a Grant relationship) to a User in a Realm.

It is outside the scope of this article to go into detail about how PicketLink determines where to store relationship state, however this might be a good topic for a future deep dive.

Partitions and Multiple Configurations

PicketLink allows multiple configurations to be simultaneously declared, each with its own distinct name. A single configuration may have one or more identity stores configured for storing identity state. By supporting multiple configurations, PicketLink provides control over which backend identity store is used to store the identity state for each partition. This all might sound a little confusing, so let’s illustrate it with a diagram that describes a possible use case for a fictional paper company:

In this example our paper company has two configurations, “Public” and “Internal”. The “Public” configuration has been configured to use a JPA-based identity store which uses a database to store its identity state. The “Internal” configuration uses an LDAP-based identity store which is backed by a corporate LDAP directory. In addition to these two configurations, we also have two realm partitions - “Users” and “Employees”.

Let’s also assume that our paper company runs an ecommerce web site where anyone can log in and place an order for their products. The login page for public users might look something like this:

When logging in through this login form (which is easily found via a “Sign In” link on the main page of the site), authentication will be performed using the “Users” realm. The site may also provide an employee portal for managing orders and possibly performing other back-office tasks. Employees wishing to access this portal would use a different web address (or maybe an entirely different application, possibly even available only on the company private network) and would authenticate with an “employee-only” login form backed by the “Employees” realm. We can represent the distinct login pages and their associated realms using the following diagram:

An application may be modelled to support this multi-faceted application in a number of ways; it may be structured as a number of separate Tiers, with each tier providing a limited set of functions (possibly implemented as separate applications and/or services) and a set of tier-specific roles to control how privileges to access those functions are assigned; it could also be structured as a single monolithic application that “does everything” (™), restricting access to certain areas depending on the access level of the current user. In either case, application-wide privileges can be easily assigned to individual users from either realm. For example, if the privilege takes the form of a role or group membership, it’s possible for that role or group to exist in one realm and a user to which it is assigned exist in another realm.

Let’s say for example that an “admin” role for our paper company’s web portal is defined in the “Users” realm, and that this role is required to access the “Review Orders” page of the site:

As we can see, it doesn’t matter that the user to which this role is assigned exists in a different realm, because as we mentioned previously, relationships by their very nature are “cross-partitioned” and so can be used to assign privileges between distinct realms.

Partition Management API

PicketLink provides a simple PartitionManager API for managing partitions. It can be easily injected into your application like so:

import org.picketlink.idm.PartitionManager;
import javax.inject.Inject;

public class AdminService {
    @Inject PartitionManager partitionManager;
}

Once you have the PartitionManager instance, you can retrieve an existing Partition like so:

    Realm default = partitionManager.<Realm>getPartition(Realm.class, default);

Or you can retrieve all partitions of a certain type:

    List<Realm> realms = partitionManager.<Realm>getPartitions(Realm.class);

Creating a new Partition is also simple:

    Tier orderServices = new Tier(orderServices);
    partitionManager.add(orderServices);

As is removing a Partition:

    Realm tempUsers = partitionManager.<Realm>getPartition(Realm.class, temp);
    partitionManager.remove(tempUsers);

To create users and other identity objects within a Partition, get a reference to its IdentityManager via the createIdentityManager() method:

    Realm default = partitionManager.<Realm>getPartition(Realm.class, default);
    IdentityManager im = partitionManager.createIdentityManager(default);

    User jsmith = new User(jsmith);
    im.add(jsmith);

To grant permissions to users within a Partition, get a reference to its PermissionManager via the createPermissionManager() method:

    Realm default = partitionManager.<Realm>getPartition(Realm.class, default);
    User jsmith = new User(jsmith);
    im.add(jsmith);

    PermissionManager pm = partitionManager.createPermissionManager(default);
    pm.grantPermission(jsmith, Order.class, CREATE);

To create relationships, get a reference to a partitionless RelationshipManager via the createRelationshipManager():

    RelationshipManager rm = partitionManager.createRelationshipManager();

Once you have the RelationshipManager you can use it to create relationships either between identities in the same partition, like so:

    Realm default = partitionManager.<Realm>getPartition(Realm.class, default);
    IdentityManager im = partitionManager.createIdentityManager(default);
    User jsmith = new User(jsmith);
    im.add(jsmith);
    Role admin = new Role(admin);
    im.add(admin);

    rm.add(new Grant(jsmith, admin));

Or between relationships in different partitions:

    Realm default = partitionManager.<Realm>getPartition(Realm.class, default);
    IdentityManager im = partitionManager.createIdentityManager(default);
    User jsmith = new User(jsmith);
    im.add(jsmith);

    Tier serviceTier = partitionManager.<Tier>getPartition(Tier.class, service);
    IdentityManager tim = partitionManager.createIdentityManager(serviceTier);
    Role admin = new Role(admin);
    tim.add(admin);

    rm.add(new Grant(jsmith, admin));

Summary

PicketLink’s advanced support for partitions allows us to create security architectures suitable for simple, single-purpose applications ranging through to complex, multi-tier enterprise platforms. In this article we examined how partitions can be used to create distinct sets of identities, and we explored how to manage partitions using the PartitionManager API.

Once again, thanks for reading!

PicketLink Deep Dive - Part 1

Posted by    |       |    Tagged as Java EE PicketLink

In this series we’ll be taking a magnifying glass to PicketLink, a security framework for Java EE. Each article in the series will examine a single aspect or feature of PicketLink in detail and also illuminate some of the design decisions made during the feature’s development.

Hopefully by the end of the series we’ll have helped you to gain a greater understanding of PicketLink, and how best to use it to address the security requirements of your own Java EE application.

Resources

At the time of writing the latest stable version of PicketLink is 2.5.2.Final. The latest version of both the PicketLink Reference Documentation and API Documentation can always be found at http://docs.jboss.org/picketlink/2/latest/.

The PicketLink binary distribution can be downloaded from the following page:

http://www.jboss.org/picketlink/downloads.html

If your build is Maven-based then please refer to the PicketLink Reference Documentation for information about how to include the PicketLink dependencies in your project.

You can find the latest version of the PicketLink source code at GitHub:

https://github.com/picketlink/picketlink

Identity Model

In this issue we’ll be looking at PicketLink’s Identity Model feature, a fundamental part of the PicketLink IDM (Identity Management) submodule that forms the foundation on which the majority of PicketLink’s other features are built.

During the design process for PicketLink IDM the development team spent a lot of time trying to work out the best way for modelling common security concepts such as roles and groups, etc. Faced with challenges relating to the lack of a common (or even de facto) standard for these core concepts it was decided that PicketLink required a certain level of abstraction to allow it to be customized per-deployment depending on the application’s security needs. Striking a balance between usability (for those that just wished to use PicketLink out of the box) and customizability (for applications that had more complex, or non-standard security requirements) posed a challenge that required an elegant solution.

The answer was the Identity Model - a set of interfaces and classes that provide a basic implementation so that PicketLink would just work(™), built on top of an abstraction layer that allows for a completely custom implementation.

The Identity Model defines the identity objects (such as Users and Roles) for your project, and the relationships between those objects. This is one of the major differences between PicketLink and other security frameworks - PicketLink supports a dynamic Identity Model, which means that there isn’t a hard-coded set of User, Role or Group classes that you are forced to use in your own application (PicketLink actually does provide these classes but you may choose not to use them). Why is it so important that PicketLink supports such a high level of customization? There are actually quite a number of reasons, so let’s take the time to explore a few of them in more detail.

Region Specific Attributes

Depending on where your project is being deployed, you may have specific requirements in relation to User state based on the region that your application may be servicing. For example, an application in the United States might require a User to have an SSN property, while an application in Russia might require a property to store a user’s patronym. In western culture a person may typically have a title, first name, middle name/s and last name, however this is certainly not the rule in many other cultures. It may be argued that these property values may be simply stored as arbitrary attribute values, like so:

user.setAttribute(new Attribute(joinDate, new Date()));

However storing these property values as ad-hoc attributes means we give up on important stuff like type safety and bean validation. If the property value is one that’s required for all of your users, then It’s much more desirable to be able to define these as first class properties of your bean, like so:

user.setJoinDate(new Date());

Custom Security Requirements

Security requirements may change drastically between applications, and a security architecture that may be sufficient for one application might be unsuitable for another. Let’s take roles for example - depending on who you ask, a role within an application might mean any number of things.

In some cases, a role equates to a simple, application-wide privilege that may be assigned directly to users. In Java EE5 for example the @RolesAllowed annotation may be used to restrict access to a class or method, allowing only the users that have been granted that specific role invocation rights:

@RolesAllowed(admin)
public void setBaseInterestRate(float value);

In other cases, a role might be something that may only be assigned to a group or mapped to a principal. Or it might only be valid within the context of a group (i.e. user jsmith has the logistics_support role for the retail_sales group). Or there may even be no such thing as roles at all, with all application privileges perhaps modeled as group memberships or using some alternative design. The point is there’s no single correct way to do security.

Because of the fact that everyone has different ideas of what constitutes a Security API, it is important that PicketLink provides the flexibility to allow custom scenarios to be supported.

Backend Identity Store Compatibility

In some environments your application may be required to conform to a pre existing security model. For example a corporate LDAP directory with heavily customised user attributes or a central SSO provider over which you have no direct control, or a legacy database containing user records. In these scenarios it's important that PicketLink is able to work within the bounds of an existing security architecture, and be able to accurately model its security objects.

Identity Model Building Blocks

Let’s get more technical now about what actually constitutes an Identity Model. A core set of interfaces from the org.picketlink.idm.model package define the foundation on which an Identity Model is built. Let’s take a look at these in the following class diagram:

We’ll be covering partitions in a future article so we can ignore the Partition interface for now. That leaves us with the following four core interfaces:

AttributedType - This is the root interface of the Identity Model. It basically provides methods for defining only two simple pieces of state - a globally unique identifier value assigned by PicketLink when an identity object is created, and a set of arbitrary attribute values. This means that every identity object (including users, roles, groups, and any other identity types you might create) at the very least has a unique identifier value, and is capable of storing a custom set of named attribute values of any Serializable type.

IdentityType - This is the parent interface for all identity types. In addition to the identifier and attribute properties inherited from the AttributedType interface, it also defines properties that reflect whether the identity object is enabled or not, the partition that it belongs to and the created date and optional expiration date for the identity.

Account - This is a special marker interface, which represents an identity type that is capable of authenticating. It is typically used as the superinterface for user identity types, or identity types that represent a third party process or agent that may interact with your application. Identity types such as roles or groups do not implement the Account interface as these types are not capable of authentication (i.e. they cannot log in), instead they implement the IdentityType interface directly.

Relationship - This is the super-interface for all relationship implementations. Like the Account interface it is also a marker interface, with no additional state (beyond that declared by its parent interface IdentityType) required by its contract.

There are a couple more important ingredients that we must know about besides the core interfaces described above when creating an identity model - the @AttributeProperty annotation and the @Unique annotation. We’ll cover these in more detail in the next section.

What does an actual Identity Model look like?

Good question! To answer this, we’ll take a look at the basic Identity Model provided out of the box by PicketLink. This model defines a number of commonly used identity objects and relationships, and in many cases may be sufficient for the security requirements of many typical applications. It can be easily extended or even copied to allow for convenient customization if desired.

Agent

The Agent class represents an external non-human identity that is capable of authenticating, hence it implements the Account interface. It defines getter and setter methods for a loginName property, which is used during authentication to identify the Account. Let’s take a look at the source code for this class (for the purpose of brevity some non-essential code has been trimmed):

public class Agent extends AbstractIdentityType implements Account {
    private String loginName;

    @AttributeProperty
    @Unique
    public String getLoginName() {
        return loginName;
    }

    public void setLoginName(String loginName) {
        this.loginName = loginName;
    }
}

There’s a few significant things to note about the above code. First of all, we can see that the Agent class extends AbstractIdentityType. This abstract class provides default implementations for all the methods of the parent IdentityType interface, allowing us to concentrate on the specific business logic for this identity class. If you wish to implement your own Identity Model then this can be a great time-saver.

Secondly, the @AttributeProperty annotation indicates that this is a property of the identity object that should be automatically mapped to the backend identity store. Each identity property that must be persisted should be annotated with @AttributeProperty. An example of a property that might not be annotated would be one with a calculated value, for instance a getFullName() method that simply concatenates the user’s first and last name together, yet doesn’t persist the calculated value itself in the backend identity store.

Thirdly, the @Unique annotation is used to indicate to PicketLink that the property must contain unique values. In this example it is used to ensure that the loginName property is unique (it should be obvious why it’s important that more than one account does not have the same login name).

Finally, we can observe that creating identity properties is as simple as defining a getter and setter method, following the JavaBean standard. Property values may be any serializable type.

User

The User class extends Agent to add some human-specific properties, such as first name, last name and so forth.

public class User extends Agent {
    @AttributeProperty
    private String firstName;

    @AttributeProperty
    private String lastName;

    @AttributeProperty
    private String email;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return this.email;
    }

    public void setEmail(String email) {
        this.email = email;
    }
}

In the above code, you may notice that the @AttributeProperty annotation is on the actual field declaration itself, instead of the getter method. PicketLink allows the annotation on either the field or the getter method, similar in fashion to JPA and its annotations.

Group

The Group class is an identity type that may be used for modelling basic group-related identity privileges, such as group membership and group roles. It is intended to be used in a hierarchical structure, with each group capable of having multiple subgroups and so forth. The Group class defines three property values - the name property represents the group’s unique name within the same branch of its hierarchical structure, the parentGroup property is an optional property which may be used to specify the group’s parent group (or null if the group has no parent, i.e. it is a root group), and path which represents the fully qualified path of the group, i.e. the complete hierarchical group name structure starting from the root, delimited by a separator.

public class Group extends AbstractIdentityType {
    public static final String PATH_SEPARATOR = "/";

    private String name;
    private Group parentGroup;
    private String path;

    @AttributeProperty
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @AttributeProperty
    @Unique
    public String getPath() {
        this.path = buildPath(this);
        return this.path;
    }

    public void setPath(String path) {
        this.path = path;
    }

    @AttributeProperty
    public Group getParentGroup() {
        return this.parentGroup;
    }

    @AttributeProperty
    public void setParentGroup(Group group) {
        this.parentGroup = group;
    }

    private String buildPath(Group group) {
        String name = PATH_SEPARATOR + group.getName();

        if (group.getParentGroup() != null) {
            name = buildPath(group.getParentGroup()) + name;
        }

        return name;
    }
}

You may notice in the above code that the parentGroup property has a type of Group. This is possible because PicketLink allows identity definitions to themselves directly reference other identities via their properties. We can also notice that the getPath() method is annotated with @Unique - this is to ensure that group names are unique within their same group branch (i.e. no other group with the same parent group may have the same name).

Role

The Role class is quite similar to the Group class except that it doesn’t support a hierarchical structure, therefore its code is significantly more simple:

public class Role extends AbstractIdentityType {
    private String name;

    @AttributeProperty
    @Unique
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Relationships

Relationships are the constructs that help us to define the privileges for our identity objects by defining how they relate to each other. Relationships are typed associations between two or more identity objects.

A relationship class must implement the Relationship interface, which itself extends AttributedType - this means that every concrete relationship instance is assigned a unique identifier value, and is also capable of storing an arbitrary set of attribute values.

The basic identity model defines only three relationship types - Grant, which associates an identity with a role; GroupMembership, which similarly associates an identity with a group; and lastly GroupRole, which is used to assign a group-specific role to an identity. Let’s take a look at them in closer detail:

Grant

The Grant relationship is a simple association between a role and an assignee, and is generally used to assign coarse-grained application-wide privileges to a set of users.

public class Grant extends AbstractAttributedType implements Relationship {
    
    private IdentityType assignee;
    private Role role;

    public IdentityType getAssignee() {
        return assignee;
    }

    public void setAssignee(IdentityType assignee) {
        this.assignee = assignee;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }
}

You may notice that there is nothing special about the above code - the Grant class extends AbstractAttributedType to provide the basic framework methods, however the implementation of the relationship itself is simple a couple of fields with getter/setter methods. This simplicity is intentional - as long as your property values implement the IdentityType interface then PicketLink is perfectly capable of working with your relationship class without any further effort required. This makes it extremely easy to define new custom relationship types yourself.

If you do wish to define a non-identity attribute property for your relationship, then you may do so by annotating the property with @AttributeProperty, the same way as is done when creating an identity type. For example, let’s say we would like to store the grant date for the above relationship - we could simply add a property like this:

    private Date grantDate;

    @AttributeProperty
    public Date getGrantDate() {
        return grantDate;
    }

    public void setGrantDate(Date grantDate) {
        this.grantDate = grantDate;
    }

Then we would be able to use it like so:

Grant grant = new Grant();
grant.setGrantDate(new Date());

Alternatively, you could of course just set an arbitrary attribute value:

Grant grant = new Grant();
grant.setAttribute(new Attribute(grantDate, new Date()));

Which option you would choose is totally up to you.

GroupMembership

The GroupMembership relationship is very similar to Grant, except that it is used to associate an account with a Group.

public class GroupMembership extends AbstractAttributedType implements Relationship {
    private Account member;
    private Group group;

    public Account getMember() {
        return member;
    }

    public void setMember(Account member) {
        this.member = member;
    }

    public Group getGroup() {
        return group;
    }

    public void setGroup(Group group) {
        this.group = group;
    }
}

Once again, there is absolutely nothing special about this implementation - it simply defines two property values with getter/setter methods.

GroupRole

The GroupRole relationship is used to represent a group-specific role, similar to Grant however restricted to the scope of a single group. To simplify the implementation of this relationship it extends the Grant relationship (which already provides the assignee and role properties), and just adds a group property:

public class GroupRole extends Grant implements Relationship {
    private Group group;

    public Group getGroup() {
        return group;
    }

    public void setGroup(Group group) {
        this.group = group;
    }
}

Like the above examples, the implementation is extremely simple - a single property with getter/setter methods.

Summary

Hopefully this article has been helpful in explaining how to work with PicketLink’s identity model, both in using the provided basic model and in describing how to create your own custom model, complete with identity and relationship classes.

If you have any questions or comments please post them below, and if you have any special requests for future PicketLink Deep Dive topics please let us know also.

Thanks for reading!

PicketLink 2.5.0.Beta3 Release and Version Change

Posted by    |       |    Tagged as CDI PicketLink Seam

I'm pleased to announce the release of PicketLink 2.5.0.Beta3. This release is actually the successor to 3.0.0.Beta2 - we've changed the version number to help avoid confusion going forward, if you want the nitty gritty details about this decision then you can find out more below.

In case you don't know what it is, PicketLink is a security framework for Java EE applications. If you are already familiar with Seam Security, then you might consider PicketLink to be its spiritual successor. For more info about its features check out this overview.

As always, here's the direct links to the various resources for this release:

PicketLink 2.5.0.Beta3 Distribution Zip

Reference Documentation

API Documentation

Source on GitHub

Report Issues

Mailing List

Mailing List Archives

Forums

For those of you that use Maven, we've made a slight change to the artifact ids - from now on a typical application will only need to declare the following dependencies:

<dependency>
  <groupId>org.picketlink</groupId>
  <artifactId>picketlink-api</artifactId>
  <version>2.5.0.Beta3</version>
</dependency>

<dependency>
  <groupId>org.picketlink</groupId>
  <artifactId>picketlink-impl</artifactId>
  <version>2.5.0.Beta3</version>
  <scope>runtime</scope>
</dependency>

<!-- Optional database schema when using Identity Management with JPA based Identity Store -->
<dependency>
  <groupId>org.picketlink</groupId>
  <artifactId>picketlink-idm-schema</artifactId>
  <version>2.5.0.Beta3</version>
  <scope>runtime</scope>
</dependency>

For this release, the reference documentation has received some special attention and so should be significantly more informative than previous betas. With that being said, the team is constantly improving the docs and will continue to add more content right up to the final release. There are also numerous quickstarts planned to help you get up and running quickly with the many security features provided by PicketLink - I'll be posting some more info about some of these shortly so keep an eye on this space.

There have also been a substantial number of bug fixes, new features and improvements made since the last beta release, the details of which you'll find in the release notes below.

As always, the PicketLink team is available to chat with at various times of the day on the #picketlink IRC channel at freenode.net; also feel free to drop them a line at the PicketLink Forums if you need help using PicketLink in your own application.

Version Change

If you've been following any PicketLink-related news lately, you'll know that the PicketLink team has been working hard towards releasing PicketLink 3 in the very near future. It has recently come to the team's attention though that there is some confusion surrounding the versioning of PicketLink, which is due to a couple of reasons; firstly, there is an existing committment to support PicketLink Federation 2.1 in EAP (the supported version of JBoss Application Server, recently renamed to WildFly). Secondly, there was never an actual 2.x release of PicketLink IDM (it was only ever officially released as version 1.x). Because of this, and since the PicketLink Federation that was planned to be released as 3.0 is actually backwards compatible with 2.1, the team has decided to rename the 3.0 release to 2.5. So what does this mean exactly? Well, besides the change in version number, not much at all really - PicketLink 2.5 will still include all of the next generation security features that the PicketLink team have been working on over the past months. We apologise for any inconvenience that this change might have caused, however the team felt it was best to resolve this confusion now, before the final release.

Release Notes

Bug

  • PLINK-116 - Change scope for JBoss Logging dependency in picketlink-common module to provided
  • PLINK-119 - DefaultIdentity is considering the User.id when comparing with the DefaultLoginCredentials.userId
  • PLINK-131 - Signed logout request does not contain the "Destination" attribute
  • PLINK-132 - PicketLink based SP's need to support different login and logout URLs
  • PLINK-136 - The IDM subsystem is always initialized even when a custom Authenticator is provided
  • PLINK-137 - Change the scope for CDI dependencies in picketlink-api and picketlink-impl to provided

Enhancement

  • PLINK-126 - Introduce individual annotations for JPA schema entities and properties
  • PLINK-135 - Add type parameters to CredentialHandler

Feature Request

  • PLINK-113 - Users should be able to use a IdentityManager for any of the configured realms.
  • PLINK-117 - The API documentation should aggregate the javadocs for the modules
  • PLINK-118 - Update documentation with the File and LDAP stores configuration
  • PLINK-120 - Login logic is not considering when the user is disabled/locked
  • PLINK-121 - Throw a specific exception when the user tries to authenticate twice using the same credentials
  • PLINK-124 - Add credential storage retrieval methods to IdentityManager
  • PLINK-127 - CredentialHandler implementations should check if the Agent is disabled
  • PLINK-128 - Refactor the Configuration API to provide a Fluent API using the build pattern
  • PLINK-142 - Provide more examples about how to mix identity stores

Task

  • PLINK-92 - Container Bindings Project
  • PLINK-122 - Provide test cases for the base module
  • PLINK-125 - Umbrella task for 2.5.0.Beta3 documentation issues
  • PLINK-129 - Import the container bindings modules from PicketLink v2
  • PLINK-133 - Use getAgent() instead of getUser() throughout authentication API
  • PLINK-138 - Change project version from 3.0.0 to 2.5.0

PicketLink 3.0 Alpha1 Released

Posted by    |       |    Tagged as CDI PicketLink Seam

I'm very pleased to announce the first alpha release of PicketLink 3.0. This release is the culmination of many months of effort by the JBoss Security team, with many contributions made from other project teams at JBoss and members of the community. I'd like to thank everyone involved with this release, from those who participated in the many design discussions on the security mailing list over the last few months, to those who contributed code and have started integrating PicketLink into their own projects.

For those who don't know, PicketLink is a CDI-based application security framework for Java EE, much in the same spirit of Seam Security. In fact, PicketLink 3.0 can be considered to be the spiritual successor to Seam Security, as it is more or less based on a similar core design albeit with a much more powerful and flexible identity model and feature set.

Before I go any further, here's the links to the goodies:

PicketLink 3.0.0.Alpha1 Distribution Zip

Reference Documentation * PLEASE NOTE that the reference documentation is still being written, so please be patient with us!

API Documentation

Source Code on GitHub

Report Issues

PicketLink forums

Mailing List

Mailing List Archives

For those of you that use Maven, here's the artifact id's to add to your pom.xml:

<dependency>
  <groupId>org.picketlink</groupId>
  <artifactId>picketlink-core-api</artifactId>
  <version>3.0.0.Alpha1</version>
</dependency>

<dependency>
  <groupId>org.picketlink</groupId>
  <artifactId>picketlink-core-impl</artifactId>
  <version>3.0.0.Alpha1</version>
  <scope>runtime</scope>
</dependency>

<dependency>
  <groupId>org.picketlink</groupId>
  <artifactId>picketlink-idm-api</artifactId>
  <version>3.0.0.Alpha1</version>
</dependency>

<dependency>
  <groupId>org.picketlink</groupId>
  <artifactId>picketlink-idm-impl</artifactId>
  <version>3.0.0.Alpha1</version>
  <scope>runtime</scope>
</dependency>

<!-- Optional database schema when using Identity Management with JPA based Identity Store -->
<dependency>
  <groupId>org.picketlink</groupId>
  <artifactId>picketlink-idm-schema</artifactId>
  <version>3.0.0.Alpha1</version>
  <scope>runtime</scope>
</dependency>

Currently the Maven artifacts are located in the JBoss Maven Repository, however they are planned to be synchronized to Maven Central shortly.

This initial Alpha release primarily concentrates on authentication, authorization and identity management features. Let's take a look at a couple of these features in a little more detail, starting with simple programmatic authentication.

Programmatic authentication

This simple form of authentication should be familiar to many Seam users. To control the authentication process yourself, simply provide a bean in your application that implements the following Authenticator interface:

package org.picketlink.authentication;

import org.picketlink.idm.model.User;

public interface Authenticator {
    public enum AuthenticationStatus {
        SUCCESS, 
        FAILURE, 
        DEFERRED
    }

    void authenticate();

    void postAuthenticate();

    AuthenticationStatus getStatus();

    User getUser();
}

To make things easier, we've provided an abstract base class that's already implemented everything for you except for the authenticate() method. There's only two things you need to do yourself in the authenticate() method; 1) set the authentication status to reflect whether authentication was successful, and 2) set the User object if authentication was successful. In this example, we're going to inject DefaultLoginCredentials (a simple holder bean provided by PicketLink which can be used for traditional username/password authentication) and allow authentication if the provided username is 'jsmith' and the password is '1234':

public class MyAuthenticator extends BaseAuthenticator {
    @Inject DefaultLoginCredentials credentials;

    public void authenticate() {
        if ("jsmith".equals(credentials.getUserId()) && "1234".equals(credentials.getPassword())) {
          setUser(new SimpleUser(credentials.getUserId()));
          setStatus(AuthenticationStatus.SUCCESS);
        } else {
          setStatus(AuthenticationStatus.FAILURE);
        }
    }
}

To actually perform the authentication, simply have your application set the username and password credentials on the DefaultLoginCredentials bean, then invoke the Identity.login() method - you can either do this directly from your view layer, or define a business method in your project that injects the Identity bean and then invokes its login() method. Your Authenticator bean will be found automatically by the authentication process and its authenticate() method invoked to determine whether authentication was successful. An example might look something like this:

public @RequestScoped class LoginAction {

  @Inject DefaultLoginCredentials credentials;
  @Inject Identity identity;
  
  public void login(String username, String password) {
    credentials.setUserId(username);
    credentials.setPassword(password);
    identity.login();
  }
}

Once authenticated, the Identity bean (which by default is session-scoped) can be injected into your application's beans so that you can access the currently authenticated User.

Identity Management

PicketLink's Identity Management (IDM) module provides a formal API for managing the Users, Roles and Groups of your application. Support is provided out of the box for LDAP, Database (via JPA) or File-based identity stores, and an extensible SPI allows for the implementation of additional identity storage backends. The IDM features provided by PicketLink are far too extensive to cover in a single blog post, so let's take a look at a simple example using the JPA identity store. To make things easier we provide a default database schema, included in the picketlink-idm-schema jar file. To make use of this schema, simply add the schema jar file to your project and then add a persistence-unit entry to your project's persistence.xml file, like so:

<persistence-unit name="picketlink-default"
                      transaction-type="JTA">
    <description>PicketLink Persistence Unit</description>
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>

    <class>org.picketlink.idm.jpa.schema.IdentityObject</class>
    <class>org.picketlink.idm.jpa.schema.PartitionObject</class>
    <class>org.picketlink.idm.jpa.schema.RelationshipObject</class>
    <class>org.picketlink.idm.jpa.schema.RelationshipIdentityObject</class>
    <class>org.picketlink.idm.jpa.schema.RelationshipObjectAttribute</class>
    <class>org.picketlink.idm.jpa.schema.IdentityObjectAttribute</class>
    <class>org.picketlink.idm.jpa.schema.CredentialObject</class>
    <class>org.picketlink.idm.jpa.schema.CredentialObjectAttribute</class>

    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
        <property name="hibernate.hbm2ddl.auto" value="create-drop" />
        <property name="hibernate.show_sql" value="true" />
        <property name="hibernate.format_sql" value="true" />
        <property name="hibernate.transaction.flush_before_completion"
                  value="true" />
    </properties>
</persistence-unit>

The one other thing you must provide is an EntityManager for PicketLink to use, we can do this by writing a CDI producer field - here's an example (make sure the unitName matches the one you've configured in persistence.xml):

public class Resources {
    @SuppressWarnings("unused")
    @Produces
    @PicketLink
    @PersistenceContext(unitName = "picketlink-default")
    private EntityManager picketLinkEntityManager;
}

Once we've done that, we're ready to go! No further configuration is necessary, PicketLink provides an IDM-based Authenticator implementation that is automatically configured if the appropriate entity classes are provided.

The first thing we might want to do is to create some default users for our application. We can do this by providing a @Startup bean - here's an example in which we create a user called 'admin', to which we grant the 'administrator' application role:

@Singleton
@Startup
public class CreateDefaultUser {
    @Inject IdentityManager identityManager;

    @PostConstruct
    public void create() {
        User admin = new SimpleUser("admin");
        admin.setEmail("admin@acme.com");

        this.identityManager.add(admin);
        this.identityManager.updateCredential(admin, new Password("secret"));

        Role roleAdmin = new SimpleRole("administrator");
        this.identityManager.add(roleAdmin);

        identityManager.grantRole(admin, roleAdmin);
    }
}

The IdentityManager bean is the gateway to all of PicketLink's IDM features. It allows you to create, update and delete Users, Groups, Roles and their relationships, plus manage and validate user credentials and attributes. It can be injected into any of your project's beans any time you wish to perform Identity Management related operations.

public class MyApplicationBean {

    @Inject IdentityManager identityManager;   

}

To create a new User, Group or Role, you simply create a new instance of the object (PicketLink provides default implementations called SimpleUser, SimpleGroup and SimpleRole) and pass it to IdentityManager.add():

  User bob = new SimpleUser("bob");
  identityManager.add(bob);
  
  Group managers = new SimpleGroup("managers");
  identityManager.add(managers);
  
  Role admin = new SimpleRole("admin");
  identityManager.add(admin);

To update something, you can first look it up using the appropriate method (such as getUser(), getGroup(), etc), make your changes and then pass the object to the update() method:

  User bob = identityManager.getUser("bob");
  bob.setEmail("bob@acme.com");
  identityManager.update(bob);

To remove something, you pass it to the remove() method:

  User bob = identityManager.getUser("bob");
  identityManager.remove(bob);

Relationships are used to model typed groupings of two or more identities. PicketLink provides a few built-in relationships, and provides support for custom user-defined relationships also. The built-in relationship types are provided to address the most common identity use cases, and the IdentityManager interface declares a number of convenience methods for working with these built-in relationships. Let's take a brief look at a few examples.

Firstly, the Grant relationship is used to represent an application role. This is a role that is typically granted to a user to give them some kind of application-wide privilege. The IdentityManager.grantRole() method is used to grant an application role:

  // Grant user "bob" the "admin" role
  User bob = identityManager.getUser("bob");
  Role admin = identityManager.getRole("admin");
  identityManager.grantRole(bob, admin);

To test whether a user has an application role we use the hasRole() method:

  User bob = identityManager.getUser("bob");
  Role admin = identityManager.getRole("admin");
  boolean bobIsAdmin = identityManager.hasRole(bob, admin);

To revoke an application role, we use revokeRole():

  User bob = identityManager.getUser("bob");
  Role admin = identityManager.getRole("admin");
  identityManager.revokeRole(bob, admin);

Next, the GroupMembership relationship is used to represent a user's membership within a group. The addToGroup() method is used to add a user to a particular group:

  // Add user "bob" to the "managers" group
  User bob = identityManager.getUser("bob");
  Group managers = identityManager.getGroup("managers");
  identityManager.addToGroup(bob, managers);

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

  User bob = identityManager.getUser("bob");
  Group managers = identityManager.getGroup("managers");
  boolean isBobAManager = identityManager.isMember(bob, managers);

Lastly, to remove a member of a group we can use the removeFromGroup() method:

  User bob = identityManager.getUser("bob");
  Group managers = identityManager.getGroup("managers");
  identityManager.removeFromGroup(bob, managers);

The last built-in relationship type is the group role. This is used when we wish to grant a user a particular role for a group, but not make them a member of the group themselves. To grant a group role, we use the grantGroupRole() method:

  // Make user "bob" an admin of the "managers" group
  User bob = identityManager.getUser("bob");
  Role admin = identityManager.getRole("admin");
  Group managers = identityManager.getGroup("managers");
  identityManager.grantGroupRole(bob, admin, managers);

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

  User bob = identityManager.getUser("bob");
  Role admin = identityManager.getRole("admin");
  Group managers = identityManager.getGroup("managers");
  boolean isBobManagersAdmin = identityManager.hasGroupRole(bob, admin, managers);

Finally, to remove a group role we use the revokeGroupRole() method:

  User bob = identityManager.getUser("bob");
  Role admin = identityManager.getRole("admin");
  Group managers = identityManager.getGroup("managers");
  identityManager.revokeGroupRole(bob, admin, managers);

What's Next

We're aiming to have a beta release ready by mid-March, for which we're planning to have more polished code, more unit tests, better documentation and hopefully an actual example and/or quickstart that you can play around with yourself. For those adventurous enough to take the alpha release for a spin, we would love to hear some feedback from you about what you found easy, what you found hard and what we can do to make things better. For future releases of PicketLink we'll be focusing on adding some really cool features, such as support for OAuth, OpenID, SAML, Rule-based permissions with Drools, a RESTFul API and much more. You can also look forward to some more blog posts that delve further into some of the more complex PicketLink features such as ACL style permissions, identity and relationship queries, plus multi-domain support. If you'd like to leave us some feedback or have questions, please comment below or on the PicketLink forums, or if you'd like to contribute to the development discussion please join the security-dev mailing list, or alternatively catch us on the #picketlink irc channel on FreeNode.

Thanks and enjoy!

Seam Security 3.0.0.Alpha1 release

Posted by    |       |    Tagged as PicketLink Seam

I'm pleased to announce the availability of Seam Security 3.0.0 Alpha1. This release is a major rework of the security features from Seam 2.x, so I apologise in advance for the epic release notes. First the important stuff:

Distribution download:

https://sourceforge.net/projects/jboss/files/Seam/Security/3.0.0.Alpha1/seam-security-3.0.0.Alpha1.zip/download

Maven dependency:

<dependency>
   <groupId>org.jboss.seam.security</groupId>
   <artifactId>seam-security-impl</artifactId>
   <version>3.0.0.Alpha1</version>
</dependency>

Alternatively, you can use the API at compile time and only include the implementation at runtime.

<dependency>
   <groupId>org.jboss.seam.security</groupId>
   <artifactId>seam-security-api</artifactId>
   <version>3.0.0.Alpha1</version>
   <scope>compile</scope>
</dependency>

<dependency>
   <groupId>org.jboss.seam.security</groupId>
   <artifactId>seam-security-impl</artifactId>
   <version>3.0.0.Alpha1</version>
   <scope>runtime</scope>
</dependency>

Note: You must configure the JBoss Community Repository in your settings.xml or project POM.

JIRA:

http://jira.jboss.org/jira/browse/SEAMSECURITY

I need to stress that this is an alpha release, and as such some features might be missing or incomplete, and there are sure to be some bugs. I'd like to invite everyone to make ample use of JIRA to report anything and everything that you find out of place or missing, this will greatly help us to prepare for the subsequent releases.

With that out of the way, it's time to buckle up and see what's changed.

Split between API and Implementation

Like many of the other Seam 3 modules, we have split the security module into API and IMPL sub-modules. This was a much requested feature for Seam Security to allow for alternate implementations to be used within unit tests, etc. Core components such as Identity, Credentials and others are now based on interfaces.

Basic Authentication

Authentication via a simple authentication method ala Seam 2 is quite similar in principle. Instead of having to configure an authenticator method in components.xml (which doesn't exist any more), you simply need to provide an implementation of the org.jboss.seam.security.Authenticator interface in your application. When calling Identity.login(), the security module will search for a bean implementing the Authenticator interface and if found use it to perform authentication. This interface declares a single method, authenticate():

public interface Authenticator
{
   boolean authenticate();
}

Implementations may perform whatever logic necessary to authenticate the user, whether that be querying a database or reading user account info from a file. Credentials (containing the user's username and password) may be obtained by injecting the org.jboss.seam.security.Credentials bean directly into your Authenticator.

public class SimpleAuthenticator
{
   @Inject Credentials credentials;
   
   public boolean authenticate()
   {
      // authentication logic here
      
      return true; // if authentication successful
   }
}

One of the major changes in Seam Security is integration with PicketLink. Early on in the planning phase for Seam 3 we decided to look at ways we could unify our security efforts with the JBoss Security team. Seam already had identity management features, however it did not make sense to continue developing these features in parallel (and therefore competing) with the PicketLink IDM project, which had similar goals. With that in mind, we decided to drop the identity management features from Seam and adopt PicketLink IDM as our identity management provider.

PicketLink provides identity store implementations for storing identity-related information using either Hibernate or LDAP, however lacks a JPA implementation. Seam 3 bridges this gap by providing a JPA implementation called JpaIdentityStore, which was inspired by the JpaIdentityStore implementation in Seam 2. This is a total rewrite, and offers much more configuration flexibility when it comes to integrating with legacy db schemas which contain identity-related data. This identity store implementation may eventually make its way into the PicketLink project's code base.

To use JpaIdentityStore to provide identity management features for your own project, you need to configure it in your beans.xml (or seam-beans.xml) file (Seam-XML module is required). First you need to configure a namespace within the root element:

   xmlns:plidm="urn:java:org.jboss.seam.security.management.picketlink"

Then you need to configure the entity classes which contain things such as your user accounts, credentials, roles, and relationships:

   <plidm:JpaIdentityStoreConfiguration>
      <s:replaces/>
      <plidm:identityClass>org.jboss.seam.security.examples.idmconsole.model.IdentityObject</plidm:identityClass>
      <plidm:credentialClass>org.jboss.seam.security.examples.idmconsole.model.IdentityObjectCredential</plidm:credentialClass>
      <plidm:relationshipClass>org.jboss.seam.security.examples.idmconsole.model.IdentityObjectRelationship</plidm:relationshipClass>
      <plidm:roleTypeClass>org.jboss.seam.security.examples.idmconsole.model.IdentityRoleName</plidm:roleTypeClass>
   </plidm:JpaIdentityStoreConfiguration>

The above example is from the idmconsole demo application that is included within the Seam Security distribution. It is a simple but concise example that demonstrates how you might build an interface for managing users, roles and groups within your application.

Another important change to note is that the IdentityManager component is no longer part of Seam 3. Replacing it is a set of action beans, found in the org.jboss.seam.security.management.action package. These beans are designed to be used directly by the view layer (such as, but not limited to, JSF) to simplify the interaction between your application and the PicketLink IDM management API. If you want direct access to the API yourself, you can directly inject org.picketlink.idm.api.IdentitySession into your bean:

@Inject IdentitySession identitySession;

From the IdentitySession you can gain access to the PersistenceManager, RelationshipManager, RoleManager, etc for fine-grained control over all aspects of the identity management API. For more information, you can refer to the PicketLink documentation here:

http://anonsvn.jboss.org/repos/picketlink/idm/downloads/docs/1.0.0.GA/ReferenceGuide/en-US/html_single/index.html

API Changes, JAAS deprecation

With the move to PicketLink we have also adopted their Identity API, making use of the base PicketLink classes for User, Role and Group. As a result, we are no longer using the JAAS API within the Identity bean, and the original authentication mechanism (also based on JAAS) has been removed too. This has given us the advantage of first class support for Groups (previously in Seam 2.x, the concept of a group was to allow a grouping of roles). In Seam 3, a role is now a typed mapping between a user and a group. For example, "bob" (a user) may be a "manager" (role type) in "head office" (a group). This gives us more fine-grained control over privileges for groups of users.

Rule-based permissions

There have been a few minor changes to rule-based permissions in Seam 3. First of all, it's no longer required that you configure the rule file, as long as it's named security.drl and located in one of the standard locations for resources according to the Weld Extensions resource loader. Secondly, instead of asserting the Principal obtained from the Identity bean into the working memory, it now asserts a User object, and injects each of the Role and Group memberships assigned to the current user. As a result, you will need to modify the imports for your security rules file, here's an example:

import org.jboss.seam.security.permission.PermissionCheck;
import org.picketlink.idm.api.Role;
import org.picketlink.idm.api.Group;

Role checks performed in rules are slightly different also. Here's an example from the idmconsole demo:

rule CreateAccount
  no-loop
  activation-group "permissions"
when
  check: PermissionCheck(resource == "seam.account", permission == "create", granted == false)
  Role(roleType.name == "admin")
then
  check.grant();
end

Programmatic authorization

We have removed the @Restrict annotation from Seam 3, as this EL-based security mechanism didn't offer the kind of type safety that is encouraged by the CDI programming model. At this stage we don't have a typesafe annnotation-based replacement, however we may introduce one before the final release. For now, authorization can be performed programmatically by injecting the Identity bean into your application bean:

@Inject Identity identity;

Role checks can then be performed like this:

identity.checkRole("superuser", "Head Office", "GROUP");

If the user doesn't possess the required role, an AuthorizationException will be thrown. Simple group membership checks can be performed in a similar way:

identity.checkGroup("Head Office", "GROUP");

Permission checks are very similar to how they were in Seam 2.x, with a slight change in terminology. To align with PicketLink, we've renamed target to resource, and action to permission. The API for checking user permissions now looks like this:

void checkPermission(Object resource, String permission);

Once again, the resource parameter is used to specify the object upon which you wish to test if the current user has the necessary privileges to interact with, and the permission parameter is the name of the specific action that the user wishes to invoke on the resource. So for example, let's say we have an Account object which the current user wishes to delete. To check whether they have the necessary privileges to do this, we perform a permission check like so:

identity.checkPermission(account, "delete");

So what's next?

Here's a list of the things that didn't quite make it into the alpha, but are planned for the final release:

  • External authentication module (due shortly in Alpha2)
  • Persistent permissions (i.e. ACLs)
  • Remember Me
  • Unit Tests
  • Documentation
  • More examples
back to top