JBoss.orgCommunity Documentation
The various components of JBoss DNA are designed as plain old Java objects, or POJOs. And rather than making assumptions about their environment, each component instead requires that any external dependencies necessary for it to operate must be supplied to it. This pattern is known as Dependency Injection, and it allows the components to be simpler and allows for a great deal of flexibility and customization in how the components are configured. And, JBoss DNA will soon provide a higher-level component that leverages the JBoss Microcontainer to automatically assemble and wire together all the lower-level components.
JBoss DNA uses the Java Authentication and Authorization Service (JAAS) for its security mechanism. Not only is this the standard approach for authenticating and authorizing in Java, but it also enables JBoss DNA to integrate existing security systems.
There are quite a few JAAS providers available, but one of the best and most powerful providers is JBoss Security, which is the open source security framework used by JBoss. JBoss Security offers a number of JAAS login modules, including:
User-Roles Login Module
is a simple
javax.security.auth.login.LoginContext
implementation that uses usernames and passwords stored in a properties file.
Client Login Module prompts the user for their username and password.
Database Server Login Module uses a JDBC database to authenticate principals and associate them with roles.
LDAP Login Module uses an LDAP directory to authenticate principals. Two implementations are available.
Certificate Login Module authenticates using X509 certificates, obtaining roles from either property files or a JDBC database.
Operating System Login Module authenticates using the operating system's mechanism.
and many others. Plus, JBoss Security also provides other capabilities, such as using XACML policies or using federated single sign-on. For more detail, see the JBoss Security project.
JBoss DNA defers to JAAS to authenticate clients creating repository connections (known as JCR Sessions if using the JCR API),
and generally expects the client application to obtain the JAAS LoginContext
or .
These are then passed to JBoss DNA, which merely verifies that authentication has been done.
As we'll see in the next section, JBoss DNA has the notion of an ExecutionContext
that can be created using JAAS login or access control contexts. These execution contexts therefore contain information
about the subject.
We'll also see in the chapter on JCR how JAAS can be used for authentication when JCR Sessions are created.
One of the objects that must be supplied to many JBoss DNA components is an ExecutionContext
. Some components
require this context to be passed into individual methods, allowing the context to vary with each method invocation.
Other components require the context to be provided before it's used, and will use that context for all its operations
(until it is given a different one).
What does an ExecutionContext
represent? Quite simply, it's the set of objects that define the environment
or context in which the method or component is currently operating. It includes a way for recording and reporting
errors and problems. It includes the ability to create class loaders
given a classpath of class loader names. It also includes information about the current user.
It includes access to factories that can be used to create and convert property values. And it includes factories
for working with namespaces and fully-qualified names. In fact, as JBoss DNA evolves, more things may need to be
added. Here is what the ExecutionContext
interface looks like:
public classExecutionContext
implements ClassLoaderFactory { /** * Get the factories that should be used to create values for {@link Property properties}. * @return the property value factory; never null */ public ValueFactories getValueFactories() {...} /** * Get the namespace registry for this context. * @return the namespace registry; never null */ public NamespaceRegistry getNamespaceRegistry() {...} /** * Get the factory for creating {@link Property} objects. * @return the property factory; never null */ public PropertyFactory getPropertyFactory() {...} /** * Get the current JAAS access control context. * @return the access control context; may benull
*/ publicAccessControlContext
getAccessControlContext() {...} /** * Get the current JAAS login context. * @return the login context; may benull
*/ publicLoginContext
getLoginContext() {...} /** * Get the JAAS subject for which this context was created. * @return the subject; never null */ publicSubject
getSubject() {...} /** * Return a logger associated with this context. This logger records only those activities within the * context and provide a way to capture the context-specific activities. All log messages are also * sent to the system logger, so classes that log via this mechanism should <i>not</i> also * {@link Logger#getLogger(Class) obtain a system logger}. * @param clazz the class that is doing the logging * @return the logger, named afterclazz
; never null */ public Logger getLogger( Class<?> clazz ) {...} /** * Return a logger associated with this context. This logger records only those activities within the * context and provide a way to capture the context-specific activities. All log messages are also * sent to the system logger, so classes that log via this mechanism should <i>not</i> also * {@link Logger#getLogger(Class) obtain a system logger}. * @param name the name for the logger * @return the logger, named afterclazz
; never null */ public Logger getLogger( String name ) {...} ... }
Notice that ExecutionContext
implements the ClassLoaderFactory interface described in the
previous chapter, meaning it can be used to create other contexts. These other methods are not shown,
but can be used to create create subcontexts with different JAAS
login or access control contexts, with different namespace registry, or with different combinations of components.
The fact that so many of the JBoss DNA components take ExecutionContext
instances gives us some interesting possibilities.
For example, one execution context instance can be used as the highest-level (or "application-level") context for all of the services
(e.g., RepositoryService
, SequencingService
, etc.).
Then, an execution context could be created for each user that will be performing operations, and that user's context can
be passed around to not only provide security information about the user but also to allow the activities being performed
to be recorded for user feedback, monitoring and/or auditing purposes.
The following code fragment shows how easy it is to create various execution contexts:
ExecutionContext
context1 = newExecutionContext
(); // Create a context for a user, authenticating using JAAS ...LoginContext
loginContext = new LoginContext("username",callbackHandler);ExecutionContext
context2 = context1.with(new LoginContext("username")); // Create a context for the same user, authenticating using JAAS, and using a different callback handler ... CallbackHandler callbackHandler = ...LoginContext
loginContext = new LoginContext("username",callbackHandler);ExecutionContext
context3 = context1.with(loginContext);
These contexts can then be passed to the various components as needed.
In this chapter, we covered security and environment topics as used throughout JBoss DNA. The next chapter will cover JBoss DNA repositories, including the connector framework, how DNA's JCR implementation works with connectors, what connectors are available (and how to use them), and how to write your own connector.