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.


Back to top