Introduction
The Configuration API is a fluent interface that allows developers to configure PicketBox programmatically using a simple and intuitive API.
The aim of this API is to make it easier to chain coding of configuration options in order to speed up the coding itself and make the configuration more readable. Also, the configuration API allows developers to use and configure PicketBox in any environment, the only requirement is the Java runtime !
Some of the features provided by this API are:
-
Configuration for built-in components like authentication, identity managers, authorization managers, auditing, event handling, session managers, etc
-
Default configuration for simple usage
-
Flexible and extensible API for extensions
-
Environment agnostic. You can configure PicketBox for a web application or a Java SE application in the same way
Overview
The following diagram represents an overview of the main steps required for configuring PicketBox:
The steps are detailed as following:
-
Create a org.picketbox.core.config.ConfigurationBuilder instance
-
Call the builder`s methods to configure PicketBox's different aspects. Eg.: builder.authentication().identityManager().jpaStore().
-
After all configuration is done, build the configuration. This will consolidates all previous configuration in a immutable org.picketbox.core.config.PicketBoxConfiguration instance.
-
Create a org.picketbox.core.DefaultPicketBoxManager using the configuration instance.
The code bellow realizes the steps described above:
// step 1
ConfigurationBuilder builder = new ConfigurationBuilder();
// step 2
builder
.authentication()
.mechanism(new MyCustomAuthenticationMechanism())
.identityManager()
.ldapStore()...
.sessionManager()...
.audit();
// step 3
PicketBoxConfiguration configuration = builder.build();
// step 4
PicketBoxManager picketBoxManager = new DefaultPicketBoxManager(configuration);
// start the manager, do not forget to do that
picketBoxManager.start();
// now you can use the PicketBoxManager to authenticate and authorize your users
You must always start the PicketBoxManager before using it. This is done by invoking the PicketBoxManager.start() method.
The ConfigurationBuilder
To create the PicketBox Manager you need to define the configuration first. These configurations are consolidated in a PicketBoxConfiguration object that is built using the ConfigurationBuilder.
The ConfigurationBuilder provides methods to help you to configure:
For each functionality there is a specific documentation page. Please check the documentation index for more information about each of them.
Default Configuration
Some configuration are predefined. That means you can start using PicketBox without providing any configuration at all !
This is very useful if you want to add PicketBox to your tests or to get started using it.
The code bellow is a valid example about how to configure and use PicketBox using the default configurations:
ConfigurationBuilder builder = new ConfigurationBuilder();
PicketBoxConfiguration configuration = builder.build();
// instantiates a PicketBoxManager with the default configurations
PicketBoxManager picketBoxManager = new DefaultPicketBoxManager(configuration);
picketBoxManager.start();
// create a empty context and set the credentials
UserContext authenticatingContext = new UserContext();
authenticatingContext.setCredential(new UsernamePasswordCredential("admin", "admin"));
// authenticate the usert using the provided credentials
UserContext authenticatedContext = picketBoxManager.authenticate(authenticatingContext);
// user is authenticated
assertNotNull(authenticatedContext);
assertTrue(authenticatedContext.isAuthenticated());
When building and using a default configuration what you get is:
Most of the other features are disable by default like session management, auditing, authorization, etc.
When creating a PicketBoxManager with the default configuration the only thing you get is that users will be authenticated using a file-based identity store. Considering using LDAP or databases for real scenarios.
Advanced Usage
The Configuration API is very flexible and allows to configure every PicketBox aspect.
Althought it provides ways to configure most of PicketBox's behaviours like the built-in components for authentication, authorization and identity management, some times you may need to provide your own way to configure security for your application.
Extending the Configuration API
Let's take the PicketBox HTTP module configuration as an example. When using this module you have some specific configuration for web applications. To provide those configuration the PicketBox HTTP module extends the Configuration API.
HTTPConfigurationBuilder
public class HTTPConfigurationBuilder extends ConfigurationBuilder {
...
/**
* <p>Custom configuration for protecting web resources.</p>
* @return
*/
public ProtectedResourceConfigurationBuilder protectedResource() {
return this.protectedResource;
}
...
@Override
public PicketBoxConfiguration doBuild() {
return new PicketBoxHTTPConfiguration(this.authentication().build(), this.authorization().build(), this
.identityManager().build(), this.protectedResource.build(), this.sessionManager().build());
}
}
org.picketbox.http.config.PicketBoxHTTPConfiguration
public class PicketBoxHTTPConfiguration extends PicketBoxConfiguration {
private ProtectedResourceConfig protectedResource;
public PicketBoxHTTPConfiguration(AuthenticationConfiguration authentication, AuthorizationConfiguration authorization,
IdentityManagerConfiguration identityManager, ProtectedResourceConfig protectedResource, SessionManagerConfig sessionManager) {
super(authentication, authorization, identityManager, sessionManager);
// stores the custom configuration
this.protectedResource = protectedResource;
}
/**
* Return the {@link ProtectedResourceConfig}
*
* @return the protected resource config
*/
public ProtectedResourceConfig getProtectedResource() {
return protectedResource;
}
}
org.picketbox.http.config.ProtectedResourceConfigurationBuilder
public class ProtectedResourceConfigurationBuilder extends AbstractPicketBoxHTTPConfigBuilder<ProtectedResourceConfig> {
@SuppressWarnings("rawtypes")
private ProtectedResourceManager manager;
private List<ProtectedResource> resources = new ArrayList<ProtectedResource>();
/**
* Build a {@link ProtectedResourceConfigurationBuilder} using the {@link HTTPConfigurationBuilder}
*
* @param builder the {@link HTTPConfigurationBuilder}
*/
public ProtectedResourceConfigurationBuilder(HTTPConfigurationBuilder builder) {
super(builder);
}
/**
* Set the {@link ProtectedResourceManager}
*
* @param manager
* @return
*/
@SuppressWarnings("rawtypes")
public ProtectedResourceConfigurationBuilder manager(ProtectedResourceManager manager) {
this.manager = manager;
return this;
}
/**
* Add a resource to the protected resources providing the constraint
*
* @param pattern
* @param constraint a {@link ProtectedResourceConstraint}
* @return
*/
public ProtectedResourceConfigurationBuilder resource(String pattern, ProtectedResourceConstraint constraint) {
this.resources.add(new ProtectedResource(pattern, constraint));
return this;
}
/**
* Add a resource to the protected resources along with the roles that can access the resource
*
* @param pattern
* @param roles
* @return
*/
public ProtectedResourceConfigurationBuilder resource(String pattern, String... roles) {
this.resources.add(new ProtectedResource(pattern, ProtectedResourceConstraint.AUTHORIZATION, roles));
return this;
}
@Override
protected void setDefaults() {
if (this.manager == null) {
this.manager = new HTTPProtectedResourceManager();
}
}
@Override
protected ProtectedResourceConfig doBuild() {
return new ProtectedResourceConfig(this.manager, this.resources);
}
PicketBox HTTP Configuration Usage
HTTPConfigurationBuilder builder = new HTTPConfigurationBuilder();
// custom configuration
builder.protectedResource()
.resource("/secure/*", ProtectedResourceConstraint.ALL)
.resource("/notSecured/index.html", ProtectedResourceConstraint.NOT_PROTECTED)
.resource("/onlyRoleManager/index.html", new String[] {"Manager"})
.resource("/onlyRoleFinancial/index.html", new String[] {"Financial"});
PicketBoxHTTPConfiguration build = (PicketBoxHTTPConfiguration) builder.build();
PicketBoxManager picketBoxManager = new PicketBoxHTTPManager(build);
picketBoxManager.start();
// now you can start using PicketBox
From the last code example you can see that we are using the PicketBoxHTTPManager. This class is an extension for the DefaultPicketBoxManager that customizes how the security is handled in a web environment.
Instead of using the default PicketBoxConfiguration, this code uses a PicketBoxHTTPConfiguration with the custom configuration that should be used to create PicketBoxHTTPManager instances.