Red Hat

In Relation To Shane Bryzak

In Relation To Shane Bryzak

Securing Your Applications with PicketLink and DeltaSpike

Posted by Shane Bryzak    |    Jul 7, 2014    |    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 Shane Bryzak    |    May 9, 2014    |    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!

Addon development with Forge 2 - A Basic Primer

Posted by Shane Bryzak    |    Feb 21, 2014    |    Tagged as JBoss Forge

I had the privilege today of receiving some expert tutelage on Forge Addon development in Eclipse from the Forge Team’s George Gastaldi, and I was so impressed by how easy it was that I’m going to describe the process step by step so that you too can experience the pleasure of writing a Forge addon! This guide is written from the perspective of a complete Forge noob, so you can rest assured that it has made a very strong attempt to capture all the little important details. Also, while the addon itself won’t actually do that much, we’ll try to cover all the basics which will hopefully provide the solid foundation you need to be able to implement more complex features.

Setting up your environment

I strongly recommend that you work with the latest trunk of Forge, so fire up your terminal window and start by cloning the following repositories from GitHub:

https://github.com/forge/furnace

https://github.com/forge/furnace-cdi

https://github.com/forge/forge-core

https://github.com/jbosstools/jbosstools-forge

Once you have them all build each of them using Maven, making sure to skip the tests. You’ll need Maven 3.1 or higher for this step:

cd furnace
mvn clean install -Dmaven.test.skip=true

If all goes well you’ll get a BUILD SUCCESS message at the end:

Continue by building the other three projects (furnace-cdi, forge-code and jbosstools-forge) in order using the same Maven command.

Installing Forge

Once everything has built successfully, it’s time to install Forge. Open the forge-core/dist/target directory where you’ll find some zip files containing the Forge distribution:

You have a choice here, you can either use the (smaller) distribution zip which doesn’t come pre-packaged with all of the core addons, or you can use the larger offline distribution which has the addons packaged also. For now, I recommend you use the offline distribution, so extract it to its own folder somewhere. I generally like to install tools like this into a dedicated apps folder, and if you’re on a *nix based OS I recommend creating a symbolic link also:

Once that’s done, you need to create a FORGE_HOME environment variable pointing to this directory, and add the $FORGE_HOME/bin directory to your path (this will allow you to execute the forge shell from anywhere). This is an OS-specific step so it’s up to you to complete this by yourself. When that’s done, run the forge command from a command prompt.

(Note: If you didn’t install the offline distribution, you’ll be prompted to install the core addons. When you start forge, it will attempt to install the latest released versions, however in our case we want to install the artifacts that we just built ourselves, so to do that we must first run forge -i core,2.0.1-SNAPSHOT - alternatively just use the offline distribution and save yourself a lot of trouble.)

Forge will download a bunch of stuff and then prompt you to confirm the installation, so select Y and press Enter again.

Eventually the installation will complete and you’ll be sitting at the Forge command prompt:

From here you can press the tab key to see the available commands:

We’ve successfully set up the Forge shell! Let’s quit out for now by typing exit then pressing enter and we’ll go through the steps to install the JBoss Tools Forge plugin in Eclipse.

Installing the Forge Eclipse Plugin

At the time of writing I’m using the latest release version of Eclipse, Kepler SR1. If you are using an older version of Eclipse then I recommend that you update to the latest, otherwise results might be unpredictable. The first step in installing the Eclipse plugin is to start up Eclipse, then go to the Help -> Install New Software… menu option:

Then click the Add button, then in the popup window click Archive:

Browse to the jbosstools-forge/site/target directory, select the forge.site.XXX zip file and click OK:

Click OK again in the Add Repository window, then select the checkbox next to JBoss Tools Forge Nightly Build Update Site, then click the Next button:

You’ll be prompted to review the install details, so click the Next button again. You’ll be asked to review and accept the terms of the license agreement, so after accepting them click the Finish button and Eclipse will go ahead and install the plugin. If you get a security warning about unsigned content don’t panic; it’s just a warning and it's fine to click OK here. Once finished, Eclipse will inform you that it needs to be restarted so go ahead and click the Yes button. After Eclipse has restarted you can confirm that the Forge plugin has been successfully installed by pressing Ctrl + 5, which will present you with the following popup window:

If you can see the Forge command window after pressing Ctrl + 5, then congratulations on making it this far! Next we’ll go ahead and create our Forge Addon project.

Creating a Forge Addon Project

Forge does a great job of doing the heavy lifting when it comes to creating a new Addon. Let’s create the initial project structure for our addon by opening the Forge command window in Eclipse with Ctrl + 5, then scrolling down until we find the Project/Generation - Project: New option:

Clicking on the Project: New option gives us a dialog window that lets us enter some basic details for our addon project. Fill in the details for the project name, top level package, version, final name and project location. Select Forge Addon for the project type and leave the Build system default of Maven, then click Next.

On the next screen, click the checkbox next to Create API, Impl, SPI, Tests and Addon modules and select the following addons from the addon list:

org.jboss.forge.addon:projects

org.jboss.forge.addon:ui

org.jboss.forge.furnace.container:cdi

After you’ve selected these addons, click the Finish button to generate the new project.

After grinding away for a few seconds you should see the following new projects in the Eclipse project explorer:

Our new addon project is created! Next we’ll start adding some basic functionality.

Making the Addon do something

This is where we get into the exciting stuff. Let’s start off by creating a new class in the impl project, under the com.acme.helloworld.ui package called HelloWorldUICommand. Once you’ve created this class, edit its code and make it extend AbstractUICommand:

package com.acme.helloworld.ui;

import org.jboss.forge.addon.ui.command.AbstractUICommand;

public class HelloWorldUICommand extends AbstractUICommand {

}

Once that’s done, tell Eclipse to add the unimplemented methods:

package com.acme.helloworld.ui;

import org.jboss.forge.addon.ui.command.AbstractUICommand;
import org.jboss.forge.addon.ui.context.UIBuilder;
import org.jboss.forge.addon.ui.context.UIExecutionContext;
import org.jboss.forge.addon.ui.result.Result;

public class HelloWorldUICommand extends AbstractUICommand {

    @Override
    public void initializeUI(UIBuilder builder) throws Exception {
        // TODO Auto-generated method stub
        
    }

    @Override
    public Result execute(UIExecutionContext context) throws Exception {
        // TODO Auto-generated method stub

    }

}

Let’s write a bare minimum amount of code so that we can install our plugin and try it out. Implement the execute() method by adding the following code:

package com.acme.helloworld.ui;

import org.jboss.forge.addon.ui.command.AbstractUICommand;
import org.jboss.forge.addon.ui.context.UIBuilder;
import org.jboss.forge.addon.ui.context.UIExecutionContext;
import org.jboss.forge.addon.ui.result.Result;
import org.jboss.forge.addon.ui.result.Results;

public class HelloWorldUICommand extends AbstractUICommand {

    @Override
    public void initializeUI(UIBuilder builder) throws Exception {
        // TODO Auto-generated method stub
        
    }

    @Override
    public Result execute(UIExecutionContext context) throws Exception {
        return Results.success("Hello World");
    }

}

Once that’s done, save the class and build the project by running mvn clean install in the parent folder of your addon project:

Then in Eclipse, select the helloworld-addon project (or whatever you have called it), press Ctrl + 5 to display the Forge command window and select the Addon/Manage - Install an Addon command:

Leave the default values in the Install an Addon window unchanged and click the Finish button:

If everything has gone to plan, you should notice a little popup window in the bottom right corner of the screen confirming that the addon was successfully installed. We can test our new addon immediately by pressing Ctrl + 5 and scrolling down until we find our new command:

Clicking on the command should give us another popup window that displays our hello world message:

Creating User Interface Elements

The next step is to create some user interface elements that prompt the user for input. We’ll start simple by injecting a simple text input control and adding it to the dialog screen for our addon - here’s a complete code listing:

package com.acme.helloworld.ui;

import javax.inject.Inject;

import org.jboss.forge.addon.ui.command.AbstractUICommand;
import org.jboss.forge.addon.ui.context.UIBuilder;
import org.jboss.forge.addon.ui.context.UIExecutionContext;
import org.jboss.forge.addon.ui.input.UIInput;
import org.jboss.forge.addon.ui.result.Result;
import org.jboss.forge.addon.ui.result.Results;

public class HelloWorldUICommand extends AbstractUICommand {

    @Inject UIInput<String> input;
    
    @Override
    public void initializeUI(UIBuilder builder) throws Exception {
        builder.add(input);
    }

    @Override
    public Result execute(UIExecutionContext context) throws Exception {
        return Results.success("Hello World");
    }

}

Rebuild the project the same way as before, and reinstall the addon from the Forge command screen (Ctrl + 5 and select Addon/Manage : Install an Addon). Press Ctrl + 5 again and select HelloWorldUICommand, and you should now see the following dialog window:

We can customize our input control further by adding a @WithAttributes annotation - add the following import:

import org.jboss.forge.addon.ui.metadata.WithAttributes;

Then add the @WithAttributes annotation to the UIInput:

@Inject @WithAttributes(label = "Name", required = true, description = "Enter your name")  
    UIInput<String> input;

The control can be customized by setting the various member values:

label - The label for the input

required - Make the input a required field

description - The description when you mouse over the field.

Save your class, then build and reinstall the addon following the same steps as before. Execute the addon command using Ctrl + 5 and you should now see this:

We can now begin to see how simple it is to build a user interface for our addon. Let’s extend it further by adding a select control that allows you to select a Maven dependency. In this example I’ll use the PicketLink project as our guinea pig. We’ll need to @Inject a DependencyResolver to locate the dependencies that we’re interested in, and a UISelectOne control to allow the user to select one of the dependencies. Add this code to your class:

@Inject DependencyResolver dependencyResolver;    
    
@Inject @WithAttributes(label = "Version", required = true, description = "Select the version of PicketLink") 
private UISelectOne<Coordinate> version;    
    
@Override
public void initializeUI(UIBuilder builder) throws Exception {
    builder.add(input);
        
    DependencyQuery query = DependencyQueryBuilder
            .create("org.picketlink:picketlink-api")
            .setFilter(new NonSnapshotDependencyFilter());

    List<Coordinate> coordinates = dependencyResolver.resolveVersions(query);
    version.setValueChoices(coordinates);
    builder.add(version);        
}

The DependencyQuery is used to to declare the criteria that we’ll use to locate the dependencies we want, and the NonSnapshotDependencyFilter parameter tells the query that we’re only interested in non SNAPSHOT releases. The Coordinate class is used to represent a specific Maven dependency and contains property values for the dependency’s groupId, artifactId and so forth. We populate the select control with our list of Coordinates and finally add the control to the form via the builder.add() method. Once you’re done the complete code listing should look like this:

package com.acme.helloworld.ui;

import java.util.List;

import javax.inject.Inject;

import org.jboss.forge.addon.dependencies.Coordinate;
import org.jboss.forge.addon.dependencies.DependencyQuery;
import org.jboss.forge.addon.dependencies.DependencyResolver;
import org.jboss.forge.addon.dependencies.builder.DependencyQueryBuilder;
import org.jboss.forge.addon.dependencies.util.NonSnapshotDependencyFilter;
import org.jboss.forge.addon.ui.command.AbstractUICommand;
import org.jboss.forge.addon.ui.context.UIBuilder;
import org.jboss.forge.addon.ui.context.UIExecutionContext;
import org.jboss.forge.addon.ui.input.UIInput;
import org.jboss.forge.addon.ui.input.UISelectOne;
import org.jboss.forge.addon.ui.metadata.WithAttributes;
import org.jboss.forge.addon.ui.result.Result;
import org.jboss.forge.addon.ui.result.Results;

public class HelloWorldUICommand extends AbstractUICommand {
    @Inject @WithAttributes(label = "Name", required = true, description = "Enter your name")  
    UIInput<String> input;

    @Inject DependencyResolver dependencyResolver;    
    
    @Inject @WithAttributes(label = "Version", required = true, description = "Select the version of PicketLink") 
    private UISelectOne<Coordinate> version;    
    
    @Override
    public void initializeUI(UIBuilder builder) throws Exception {
        builder.add(input);
        
        DependencyQuery query = DependencyQueryBuilder
                .create("org.picketlink:picketlink-api")
                .setFilter(new NonSnapshotDependencyFilter());

        List<Coordinate> coordinates = dependencyResolver.resolveVersions(query);
        version.setValueChoices(coordinates);
        builder.add(version);        
    }

    @Override
    public Result execute(UIExecutionContext context) throws Exception {
        return Results.success("Hello World");
    }
}

Rebuild and reinstall the addon, then invoke it from the Forge command window - you should see something that looks like this:

We can use these newfound powers to make changes to an actual project. Let’s start by modifying our addon class so that it extends AbstractProjectCommand instead of AbstractUICommand:

public class HelloWorldUICommand extends AbstractProjectCommand {

This will cause Eclipse to complain about unimplemented methods, so use Eclipse to generate them:

    @Override
    protected boolean isProjectRequired() {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    protected ProjectFactory getProjectFactory() {
        // TODO Auto-generated method stub
        return null;
    }

The isProjectRequired() method is used to determine whether this addon requires a project to execute. Since this is what we actually want, we’re going to return a value of true here:

    @Override
    protected boolean isProjectRequired() {
        return true;
    }

The getProjectFactory() method provides a reference to the currently selected project. To implement this method we first need to @Inject a ProjectFactory object into our addon class:

@Inject ProjectFactory projectFactory;

Then we simply return this value in the method body:

    @Override
    protected ProjectFactory getProjectFactory() {
        return projectFactory;
    }

So far so good! Now, since our goal is to add some dependencies to our project we need to somehow take the selected Coordinate value from our UISelectOne control and use it to add a dependency to the current project. Lucky for us Forge provides all of the tools to make this happen - first of all we’re going to inject a DependencyInstaller into our class:

@Inject DependencyInstaller dependencyInstaller;

Then, in the execute() method we’re going to use a DependencyBuilder to create a reference to the Dependency based on the Coordinate value contained in the UISelectOne control, after which we’ll tell the DependencyInstaller to install that Dependency into the selected project:

DependencyBuilder builder = DependencyBuilder.create();
builder.setCoordinate(version.getValue());

dependencyInstaller.install(getSelectedProject(context), builder);

The complete code listing should now look like this:

package com.acme.helloworld.ui;

import java.util.List;

import javax.inject.Inject;

import org.jboss.forge.addon.dependencies.Coordinate;
import org.jboss.forge.addon.dependencies.DependencyQuery;
import org.jboss.forge.addon.dependencies.DependencyResolver;
import org.jboss.forge.addon.dependencies.builder.DependencyBuilder;
import org.jboss.forge.addon.dependencies.builder.DependencyQueryBuilder;
import org.jboss.forge.addon.dependencies.util.NonSnapshotDependencyFilter;
import org.jboss.forge.addon.projects.ProjectFactory;
import org.jboss.forge.addon.projects.dependencies.DependencyInstaller;
import org.jboss.forge.addon.projects.ui.AbstractProjectCommand;
import org.jboss.forge.addon.ui.context.UIBuilder;
import org.jboss.forge.addon.ui.context.UIExecutionContext;
import org.jboss.forge.addon.ui.input.UIInput;
import org.jboss.forge.addon.ui.input.UISelectOne;
import org.jboss.forge.addon.ui.metadata.WithAttributes;
import org.jboss.forge.addon.ui.result.Result;
import org.jboss.forge.addon.ui.result.Results;

public class HelloWorldUICommand extends AbstractProjectCommand {
    
    @Inject ProjectFactory projectFactory;

    @Inject @WithAttributes(label = "Name", required = true, description = "Enter your name")  
    UIInput<String> input;
    
    @Inject DependencyInstaller dependencyInstaller;

    @Inject DependencyResolver dependencyResolver;    
    
    @Inject @WithAttributes(label = "Version", required = true, description = "Select the version of PicketLink") 
    private UISelectOne<Coordinate> version;    
    
    @Override
    public void initializeUI(UIBuilder builder) throws Exception {
        builder.add(input);
        
        DependencyQuery query = DependencyQueryBuilder
                .create("org.picketlink:picketlink-api")
                .setFilter(new NonSnapshotDependencyFilter());

        List<Coordinate> coordinates = dependencyResolver.resolveVersions(query);
        version.setValueChoices(coordinates);
        builder.add(version);        
    }

    @Override
    public Result execute(UIExecutionContext context) throws Exception {
        DependencyBuilder builder = DependencyBuilder.create();
        builder.setCoordinate(version.getValue());

        dependencyInstaller.install(getSelectedProject(context), builder);
        
        return Results.success("Hello World");
    }

    @Override
    protected boolean isProjectRequired() {
        return true;
    }

    @Override
    protected ProjectFactory getProjectFactory() {
        return projectFactory;
    }
}

Rebuild and reinstall your addon, then select a project in Eclipse and invoke our addon from the Forge command window. Keep in mind that we’ll be adding some new dependencies to the project you select so make sure it’s not something too important! I suggest you use the addon project itself as it is quite easy to remove the dependencies afterwards. Enter any value for the Name field (since we’ve marked it as required we’re forced to at least enter something) and select one of the dependencies from the Version control:

Click the Finish button and you should see the Hello World popup window appear briefly confirming that our addon ran successfully. To check it actually did something, open the project’s pom.xml in an editor and you should notice that Forge has added the selected dependency by declaring it in the <dependencyManagement> section:

And also adding the dependency itself to the <dependencies> section:

Congratulations, you’ve made it to the end! You’ve now created your first useful Forge addon that can add dependencies to an existing project. Hopefully this guide has helped by providing a high level overview of the Forge Addon architecture and a beginner’s primer on creating a new Forge Addon.

Summary

In this guide we went through the steps to build and install both the Forge Shell and Forge Eclipse Plugin, then learned how to create a new Forge Addon project. We also learned how to build and install our Addon, create custom dialog windows and have our Addon make changes to an existing project. If you’d like to learn more about Forge, then the following resources are available:

Forge web site: http://forge.jboss.org/

Documentation: http://forge.jboss.org/docs/index.html

Source code: https://github.com/forge

Thanks for reading!

PicketLink Deep Dive - Part 1

Posted by Shane Bryzak    |    Nov 13, 2013    |    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 Shane Bryzak    |    May 22, 2013    |    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 Shane Bryzak    |    Mar 3, 2013    |    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!

JUDCon India Recap

Posted by Shane Bryzak    |    Feb 3, 2012    |    Tagged as Events

I recently had the pleasure of attending Red Hat's first JUDCon event in APAC, JUDCon India. The conference was hosted by Saltmarch Media in the Nimhans Convention Centre in Bangalore, and ran for 2 days. The sessions were organized into 3 separate tracks:

  • JBoss Application Server 7
  • OpenShift and Cloud
  • Rules, Workflow , SOA and EAI

It was a great opportunity to be able to interact with so many other JBoss developers and users, and with an attendance of around 800 people it was the biggest JUDCon ever. There was a high level of energy in the atmosphere, and most sessions were packed full of people, some with standing room only. It was also great to see so much interest in JBoss technologies - the sessions I attended (and presented) all received a substantial number of questions at their conclusion, sometimes even running into the next session. On the first evening of the conference we held an open Q&A session, allowing the audience to ask whichever questions they liked to a panel of JBoss project leads and experts.

All in all, it was an awesome event. If you are interested in attending a JUDCon, then don't worry, you'll get another chance! The next one will be held in Boston - If you are able to attend, I highly recommend you do as you won't get a better chance to network with the core developers at JBoss.

We'll also be making the videos of the sessions available online, so keep an eye out for them soon!

JBoss Seam 3.1 Final Released

Posted by Shane Bryzak    |    Jan 16, 2012    |    Tagged as Seam

I'm pleased to announce the immediate availability of Seam 3.1 Final.

Links:

Download Seam 3.1.0.Final bundled distribution

Reference Documentation

API Documentation

Report issues

Maven users, please update your project to include the following:

<dependencyManagement>
   <dependencies>
      <dependency>
         <groupId>org.jboss.seam</groupId>
	 <artifactId>seam-bom</artifactId>
         <version>3.1.0.Final</version>
         <scope>import</scope>
         <type>pom</type>
       </dependency>
    </dependencies>
</dependencyManagement>

What's changed since Seam 3.0?

Existing modules

Solder

The Solder module now incorporates an exception handling framework (formerly Seam Catch), XML-based configuration (formerly Seam Config) and Servlet integration (formerly Seam Servlet). The integration of these core features into Solder means they will now be available without having to declare an explicit dependency on them.

Seam Transaction

Previously part of the Seam Persistence module, Seam Transaction is a new module that provides transaction-related features for your POJO-based beans.

New modules

Seam Social

The Seam Social module provides various useful integrations with social networks such as Twitter, Facebook and LinkedIn.

Seam Reports

Seam Reports integrates with a number of reporting engines to provide report generation features from your Seam application.

Seam JCR

The Seam JCR module allows easy interaction with a JCR (Java Content Repository) repository, and currently supports both Apache Jackrabbit and Modeshape implementations.

Seam Spring

The Seam Spring module allows you to integrate your Spring application with CDI, allowing injection of Spring beans into your CDI bean, and the injection of your CDI beans from a Spring application context.

Seam JMS

The Seam JMS module allows you to inject JMS resources, such as Connections, Topics, Queues and more directly into your beans, and also provides a bidirectional bridge between the JMS message bus and CDI, allowing JMS events to be propagated to the CDI event bus, and vice versa.

Seam Mail

Seam Mail provides a number of features that makes working with JavaMail easier, and comes with a pluggable template engine for the composition of mail content, and simple mail server configuration options.

Fixed Issues

In additional to the new modules listed above, we've also resolved 249 issues identified with the Seam 3.0 release as well as numerous documentation and example improvements.

Enjoy!

JBoss Seam 3.1.0.CR1 Released

Posted by Shane Bryzak    |    Dec 1, 2011    |    Tagged as Seam

I'm happy to announce the immediate availability of the first candidate release for Seam 3.1. Here's the usual links:

Download Seam 3.1.0.CR1 bundled distribution

Reference Documentation

API Documentation

Report issues

Maven users, please update your project to include the following:

<dependencyManagement>
   <dependencies>
      <dependency>
         <groupId>org.jboss.seam</groupId>
         <artifactId>seam-bom</artifactId>
         <version>3.1.0.CR1</version>
         <scope>import</scope>
         <type>pom</type>
       </dependency>
    </dependencies>
</dependencyManagement>

This release is now feature complete - we will only be working on bug fixes and quality issues leading up to the 3.1 final release, which can be expected in mid December. I encourage everyone to try it out, and let us know if you experience any issues with it by using the Report issues link above.

Note - the version of Solder that was included in the seam-bom of this release is incorrect, however this should not have any adverse effects.

Seam.Next Announcement

Posted by Shane Bryzak    |    Nov 30, 2011    |    Tagged as CDI Seam

I’m very happy to announce the details for the first phase of our Seam.Next plan. I’d like to thank everyone for waiting patiently while we worked on this, and for providing feedback either directly via e-mail or IRC, or through the Seam forums. I’d also like to thank the module leads, key community members and other people that were involved in helping to shape this plan, it was very much a collaborative effort and we are very excited about the ideas and goals that were discussed and direction going forward.

Before I get into the nitty gritty of the details, I’d first like to describe the motivations for wanting to make such significant changes, and talk about the overall goals that drive us. I think the best starting point for describing this is Seam 2.

Seam 2

Looking back at how we did things in Seam 2, I think it’s safe to say that many of the aspects of the framework were quite successful. I think that one of the most defining factors of its success was the integration - Seam 2 provided the core framework features (Dependency Injection, Contexts, Events, etc) and enough useful features built on top of that core framework to make application development quite a productive activity.

It also provided integration with a number of third party technologies, such as Drools, jBPM, Wicket, Spring and others. On top of that, it provided excellent documentation that tied the whole lot together, and did a pretty good job of bringing new developers up to speed, and not to mention decent tooling in the form of seam-gen and JBoss Tools.

All in all, Seam 2 has proven to be a mature, well rounded framework that solved many of the problems that developers face when building modern web applications.

Along Came CDI

CDI changed everything. By standardizing many of the core framework features of Seam and making them part of the Java EE platform, with an added focus on type-safety and extensibility, there is no longer a requirement to BYO framework - any compliant Java EE 6 container provides a comprehensive programming model out of the box, without having to supplement it with additional libraries to provide core services.

This was a great step forward - writing your application against a standard is a good thing. It helps you to avoid vendor lock-in, and means that as a developer your knowledge is portable. It also puts you into a great position for tapping into a growing ecosystem of extensions and tooling.

CDI Everywhere

Since CDI was released, one of the principles underlying all our work is that of CDI Everywhere. By enabling CDI support in as many places as possible, our goal is to make developer productivity stronger than ever. To that end, we have been encouraging and assisting other project teams to provide CDI integration directly from their own projects. We believe this is one of the key ingredients in strengthening the CDI ecosystem, and providing an environment where the developer can concentrate more on solving business problems and less on fighting with his tools.

This of course means that you no longer require an integration framework like Seam to provide support for a number of CDI-enabled technologies, such as Drools and jBPM (CDI support coming soon), GWT, Wicket and many others. Furthermore, since the tooling we provided for Seam 2 (i.e. seam-gen and JBoss Tools) was based on its proprietary core framework, any new tooling going forward should naturally be focused on the now standards-based component model provided by CDI. This is the reason why Forge is now a standalone, top level project in its own right, with a focus on building Java EE applications.

Seam 3

Looking at the previous diagram, we can now see that as a result of standardization, quite a few of the bits that made up Seam have moved outside the scope of the original project. This has meant a change in focus for Seam. Instead of providing a fully integrated framework stack, Seam 3 has taken the remaining bits and turned them into a collection of portable extensions for CDI. Essentially, what we did was implement many of the most useful features that were present in Seam 2, as well as adding a number of new features, in a modular structure so that Java EE developers can easily add support for these features to their application by simply dropping a jar file into their project.

At this point, in hindsight we think we made a poor choice here by calling this new project Seam 3, seeing as the nature of the project has changed so drastically from the previous version. While it is most definitely a worthwhile goal to create a set of useful extensions for CDI, Seam 3 by itself is no longer the fully integrated framework stack that Seam 2 was. As a direct result of this change in focus many of you have been disappointed with the documentation and getting started experience for new users.

What do users want?

The feedback we received from the community covered a broad spectrum of concerns, however there were some common areas such as:

  • Documentation
  • Getting Started Experience
  • Tooling
  • Lack of Drools/jBPM support
  • Lack of certain features, e.g. entity framework
  • Lack of migration guide

Underlying these, we also noticed two strong messages:

  • Some developers are interested mainly in portability. They don’t want their application locked into any particular container implementation, and it’s important to them that they have the freedom to use the framework in different environments.
  • Many developers just want an end-to-end framework that works, without having to piece together all the bits themselves and work out how to integrate them. They don’t want to have to read multiple sets of documentation from different projects, and their primary requirement for an application framework is productivity, i.e. getting the job done quickly and efficiently.

So the question is, how can we return to the fully integrated framework stack and productivity that Seam 2 provided, and also provide a set of portable extensions, optionally consumed a la carte, that will run in any environment where CDI is present? We’ve been working with community leaders and module leads, and have come up with a proposal that we think will rise to the challenge of addressing these concerns.

The first step we will take is to create a community-owned set of portable CDI extensions; a de-facto set of features that developers can take and use within their own applications, in whichever container they wish to deploy to. One of the major goals of this project is to grow and unify the Java EE community. By joining forces with other CDI extension developers, such as the Apache MyFaces CODI team and the CDISource team, as well as other key members of the Java EE community, we are creating a community that is stronger than the sum of its separate parts.

This must be a real community project, without any corporate affiliation to ensure that the project remains neutral. We’ve identified Apache as being a great place to host this project, as they are a non-profit organization with no corporate agenda, and have a strong reputation in the community for producing successful open source projects. So without further ado, let me introduce the Apache DeltaSpike project.

Apache DeltaSpike

By the time you’re reading this the proposal for Apache DeltaSpike has been submitted to the Apache Incubator and begun the process toward becoming a top level Apache project. DeltaSpike is a set of portable CDI extensions, built collaboratively by the Java EE community. It will be seeded by code contributed from various Java EE open source vendors, and provide a number of essential features for building enterprise applications. Portability will be the main principal of this project, satisfying the need of many developers for a framework that will run in a number of different environments.

After its initial release, the existing Seam development team (consisting of both full time and volunteer contributors), along with the MyFaces CODI team, CDISource team and other members of the greater Java EE community will carry out ongoing development on DeltaSpike - this includes the creation of new features and innovations, bug fixes and other enhancements. While it is not my place to talk about the release schedule for DeltaSpike (this is decided by the Apache DeltaSpike Podling Project Management Committee (PPMC)), I am 100% confident that it will be a lively, active project that receives the attention and contributions that it deserves, and produce many ongoing releases.

The first release of Apache DeltaSpike will consist of a common core, a set of extensions that will provide the base on which to build other extensions. It will be tested extensively across multiple Java EE containers to ensure portability, and provide a solid foundation for the development of other features. Eventually the plan is for Apache DeltaSpike to incorporate many of the features that you can find today in Seam.

An Integrated Framework

We have also mentioned that we’d like to address the needs for developers that require an end-to-end development stack. While we’re still working out the details for this, I’d like to reassure everyone that it is a high priority for us to provide a fully integrated framework in the spirit of Seam 2 but with even better productivity. We have some great ideas in motion to provide a full integrated framework for your needs. We know you’ll be excited as we are about what’s in store, so please watch this space over the coming months for more details.

What about Seam?

For those developers who have already invested heavily in Seam, don’t worry, we’re looking after you also. We’ll be continuing development on Seam 3 for the foreseeable future, in fact Seam 3.1 which is due for release shortly contains a number of exciting new modules and other improvements. We’d like to also reiterate that we are fully committed to the Seam Community - the initiatives that we’ve described above are all for the benefit of you guys, to give you the most productive framework and tools for building your applications that run the world. We ask that you be patient with us as we roll out this vision over the coming months, and thank you for your continued support.

back to top