JBoss Community Archive (Read Only)

PicketBox

PicketBox CDI

Introduction

PicketBox CDI code was moved to the PicketLink Extensions project.

If you are using PicketBox CDI we recommend to follow these instructions.

PicketBox CDI is an API to secure CDI (Contexts and Dependency Injection for the Java EE Platform, JSR-299) environments using PicketBox. It's architecture is based on extensions/customizations for the PicketLink project and on native support for Identity Management using the PicketLink IDM project.

images/author/download/attachments/54493277/pb-cdi-arc.png

We provide a example application using PicketBox CDI. You can get it here:

For more information about installing and running the quickstarts, check the PicketBox Quickstarts documentation.

PicketLink CDI

PicketLink CDI provides a powerful security API design based on some concepts from JBoss Seam. If you ever worked with JBoss Seam you'll notice that some concepts like the Identity component are still present, making the transition even easier if you want to use PicketBox CDI in your application.

This API exposes methods for:

  • Authenticating users

  • Authorizing users

  • Permission Management

Behind the scenes, most of the work is transparently delegated to PicketBox that provides a set of built-in features for authentication, authorization, identity management, session management and so forth.

This approach allows you to use a common and well known API design like the one provided by PicketLink with the set of features and built-in components provided by PicketBox.

PicketLink IDM

PicketLink IDM provides a rich API for Identity Management. It allows to quickly enable your application with users, roles, groups and membership management using different identity stores like LDAP or Databases.

This API allows you to:

  • CRUD and query users and their attributes

  • CRUD and query roles

  • CRUD and query groups

  • Maintain relationships between users, roles and groups

PicketBox CDI makes even easier the Identity Management by providing a simple configuration model (using the PicketBox Configuration API) and exposing some of the key components from the PicketLink IDM API like the IdentityManager.

For more information, see:

Configuration

To enable your application with PicketBox CDI you need to:

  • Configure PicketBox CDI dependencies in your pom.xml. If you are using Apache Maven

  • Configure a CDI Interceptor in your beans.xml

  • Create a @Producer method to produce the PicketBoxCDI configuration

Security Interceptor Configuration

Add the following interceptor to your beans.xml.



In web applications the beans.xml is usually located at WEB-INF/beans.xml.

<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>

Maven Dependencies

<!-- PicketBox CDI -->
<dependency>
    <groupId>org.picketlink.extensions</groupId>
    <artifactId>picketlink-extensions-core</artifactId>
    <version>${picketlink.extensions.core.version}</version>
</dependency>

Configuration Producer

PicketBox provides a easy and intuitive fluent API Configuration API to build its configuration.

That said, the only thing you need is create a CDI bean with a @Producer method to produce a org.picketbox.core.config.ConfigurationBuilder instance.

/**
 * <p>Bean responsible for producing the {@link ConfigurationBuilder}.</p>
 */
public class PicketBoxConfigurer {

    /**
     * <p>Produces the {@link ConfigurationBuilder}.</p>
     *
     * @return
     */
    @Produces
    public ConfigurationBuilder produceConfiguration() {
        ConfigurationBuilder builder = new ConfigurationBuilder();
        
        // just use the builder to configure the PicketBox behaviour.

        return builder;
    }

}

The example above is a simple example of how you can configure PicketBox using the default configurations.

For more information about the PicketBox default configurations, check the Configuration API documentation.

How to use

Authentication

To authenticate your users you need to @Inject both org.picketlink.Identity and org.picketlink.extensions.core.pbox.LoginCredential instances.

After that you need to populate the LoginCredential instance with the user credentials and use the Identity instance to authenticate/login your user.

/**
 * <p>Simple bean for authenticating users.</p>
 */    
public class LoginBean {

    @Inject
    private Identity identity;

    @Inject
    private LoginCredential credential;

    /**
     * <p>Performs the authentication.</p>
     */    
    public void login(String userName, String password) {
        // creates a PicketBox UsernamePasswordCredential.
        credential.setCredential(new UsernamePasswordCredential(userName, password));

        this.identity.login();
        
        if (this.identity.isLoggedIn()) {
            // user is authenticated
        } else {
            // authentication failed
        }
    }

}

Logout

To logout your users you also need to use a valid Identity instance, like bellow:

/**
 * <p>Simple bean to logout users.</p>
 */
public class LogoutBean {

    @Inject
    private Identity identity;

    /**
     * <p>Performs the logout.</p>
     */
    public void logout() {
        if (this.identity.isLoggedIn()) {
            this.identity.logout();
        }
    }

}

Authorization

PicketBox CDI provides some annotations to perform authorization. For now, only two annotations are provided: org.picketlink.extensions.core.pbox.authorization.RolesAllowed and org.picketlink.extensions.core.pbox.authorization.UserLoggedIn.

@RolesAllowed

This annotation provides a simple role based authorization for method invocations.

@RolesAllowed ({"Manager"})
public void onlyForManagersOperation() {

}

public void unProtectedMethod() {

}

@RolesAllowed ({"Executive"})
public void onlyForExecutives() {

}

@UserLoggedIn

This annotation enforces that only authenticated users can perform some method invocation.

@UserLoggedIn
public void onlyForAuthenticatedUsers() {

}

Event Handling

Both PicketBox CDI and PicketLink CDI provide important events that you may want to observe. The list above summarizes those events.

Class

Description

org.picketbox.core.authentication.event.UserAuthenticatedEvent

PicketBox event that is fired during the authentication process. You can use it to know the authentication status, get the principal, etc.

org.picketlink.authentication.event.LoggedInEvent

PicketLink event that is raised when user successfully logs in.

org.picketlink.authentication.event.LoginFailedEvent

PicketLink event that is fired when an authentication attempt fails.

org.picketlink.authentication.event.PostAuthenticateEvent

PicketLink event that is raised just after authentication

org.picketlink.authentication.event.PostLoggedOutEvent

PicketLink event that is raised just after the user un-authenticates.

org.picketlink.authentication.event.PreAuthenticateEvent

PicketLink event that is raised just before authentication.

org.picketlink.authentication.event.PreLoggedOutEvent

PicketLink event that is raised just before the user un-authenticates.

The code bellow shows how you can observe events:

/**
 * <p>
 * Simple bean that observes for some security events.
 * </p>
 *
 */
@ApplicationScoped
public class EventHandler {

    /**
     * <p>
     * Method that observes PicketBox {@link AuthenticationEvent} events.
     * </p>
     *
     * @param event
     */
    @SuppressWarnings("rawtypes")
    public void onAnyAuthenticationEvent(@Observes AuthenticationEvent event) {
    }

    /**
     * <p>
     * Method that observes PicketBox {@link AuthenticationEvent} events. An event will be raised for any successfull
     * authentication performed by the registered {@link AuthenticationManager} instances.
     * </p>
     *
     * @param event
     */
    public void onUserAuthenticatedEvent(@Observes UserAuthenticatedEvent event) {
        AuthenticationStatus status = event.getResult().getStatus();

        // list of messages gathered during the authentication
        List<String> messages = event.getResult().getMessages();

        if (status.equals(AuthenticationStatus.SUCCESS)) {
            Principal principal = event.getResult().getPrincipal();
            // handle a successfull authentication
        } else if (status.equals(AuthenticationStatus.FAILED)) {
            // handle a failed authentication
        }
    }

}

Identity Management

If you want to use the Identity Management features you need to specify that when creating your PicketBox configuration.

/**
 * <p>Bean responsible for producing the {@link CDIConfigurationBuilder}.</p>
 */
public class PicketBoxConfigurer {

    @Inject
    private DefaultEntityManagerLookupStrategy entityManagerLookupStrategy;
    
    @Produces
    public ConfigurationBuilder createConfiguration() {
        ConfigurationBuilder builder = new ConfigurationBuilder();

        builder
            .identityManager()
                .jpaStore()
                    .entityManagerLookupStrategy(this.entityManagerLookupStrategy);

        return builder;
    }

}
The configuration above tells that we want to use a JPA-based Identity Store. Which means that users. groups, roles, etc will be stored using a database. If you do not provide any specific Identity Management configuration, PicketBox will use a File-based Identity Store instead.

The Identity Management support (using PicketLink IDM) can be done in two ways:

  • You can use it to authenticate your users

  • You can use it to load roles or additional info during the authentication

  • Or both

The code above configures PicketBox to authenticate users using the PicketLink Identity Manager using a provided JPA Identity Store.

Make sure your application is properly configure with JPA. PicketBox expects to get a valid EntityManager instance from the BeanManager.

Managing Users, Roles, Groups and Memberships

If you configured PicketBox Identity Management support you are able to inject and use the PicketLink IDM org.picketlink.idm.IdentityManager to manage your users, roles, groups and memberships.

    @Inject
    private IdentityManager identityManager;

    /**
     * <p>Loads some users during the first construction.</p>
     */
    @PostConstruct
    public void loadUsers() {
        User someUser = new SimpleUser("someuser");

        // populates some basic info
        someUser.setEmail("someuser@company.com");
        someUser.setFirstName("Some");
        someUser.setLastName("User");

        this.identityManager.add(someuser);

        // update the user's password
        this.identityManager.updateCredential(someUser, new Password("123".toCharArray()));

        // create some roles
        Role roleDeveloper = new SimpleRole("developer");

        this.identityManager.add(roleDeveloper);

        Role roleAdmin = new SimpleRole("admin");

        this.identityManager.add(roleAdmin);

        // create a group
        Group groupDeveloper = new SimpleGroup("My company");

        this.identityManager.add(groupDeveloper);

        // grant some roles to the user
        this.identityManager.grantRole(someUser, roleDeveloper);
        this.identityManager.grantRole(someUser, roleAdmin);


        // add the user as a member of the group
        this.identityManager.addToGroup(someUser, groupDeveloper);

        // create a guest user
        User guest = new SimpleUser("guest");

        // populates some basic info
        guest.setEmail("guest@company.com");
        guest.setFirstName("Guest");
        guest.setLastName("User");

        this.identityManager.add(guest);
        this.identityManager.updateCredential(guest, new Password("123".toCharArray()));

        Role roleGuest = new SimpleRole("guest");

        this.identityManager.add(roleGuest);

        this.identityManager.grantRole(guest, roleGuest);
    }

The code above hows a simple example that populates the identity store using the injected IdentityManager instance during the first construction of a bean. 

Programatically RBAC

After an user is authenticated you can always check his roles by using the provided annotations (see @RolesAllowed) or programatically. 

The Identity interface from PicketLink CDI does not provide a method such as hasRoles(String) to check for roles. To overcome that PicketBox CDI provides the following approach:

UserContext user = identity.getUserContext();

if (user.hasRole("someRole")) {
    // do something
}
As you can see, you can always use the UserContext instance to check for users roles.

JBoss.org Content Archive (Read Only), exported from JBoss Community Documentation Editor at 2020-03-11 12:16:35 UTC, last content change 2013-01-24 19:42:06 UTC.