Integrating Geronimo security with the JAAS API

This section covers how Geronimo authentication integrates into the JAAS framework. For the description of JAAS concepts and how to do JAAS login, please see java documentation for the javax.security.auth.Configuration and javax.security.auth.login.LoginContext classes.

Here we just summarize what is going on and how it hooks into Geronimo.

To log into the application with the JAAS API, a client does something like this:

The first parameter passed to the LoginContext constructor is the application configuration name, it selects the JAAS login module configuration. The second parameter is a callback handler. LoginContext.login() logs the client in, and LoginContext.getSubject() returns the authenticated subject populated with Principals.

Under the covers, the LoginContext.login() method will obtain an instance of the javax.security.auth.login.Configuration class to do it's work.

java.security.auth.login.Configuration is an abstract base class that must be implemented by the JAAS service provider. The following example shows the most important method of the Configuration class that must be implemented by the Configuration provider.

org.apache.geronimo.security.jaas.GeronimoLoginConfiguration is installed as JAAS Configuration factory in the doStart() method of the GeronimoLoginConfiguration GBean by calling Configuration.setConfiguration(this) method.

Before going into details of how this works, we will compare JAAS with the Geronimo security framework. Geronimo security framework has it's own concepts of Login Domain, Security Realm, Principals, etc. Those are defined without reference to the JAAS framework. For it's implementation Geronimo security framework borrows from JAAS: Login modules, login module combination semantics, etc. This JAAS implementation artifact reutilization makes sense and makes it easier for other developers to contribute to the Geronimo security (by writing custom login modules).

But when Geronimo security framework implementation is wiring into JAAS it makes very little use of it, practically reducing it to the trivial wrapper: you just need one login module (which is JaasLoginCoordinator) and it is required to succeed. Keep this in mind when you look at the Geronimo security and JAAS glue code.

Geronimo hook into the JAAS is the implementation of the AppConfigurationEntry[] Configuration.getAppConfigurationEntry(String app-name) method in the GeronimoLoginConfiguration class derived from the abstract JAAS Configuration class.

org.apache.geronimo.security.jaas.GeronimoLoginConfiguration is a GBean that is injected with references to other GBeans that implement the org.apache.geronimo.security.jaas.ConfigurationEntryFactory interface.

You can see that implementations of the ConfigurationEntryFactory interface have names that can be retrieved with the getConfigurationName() call. Also note that ConfigurationEntryFactory interface produces just one JaasLoginModuleConfiguration instance (not an array). This is because you need just one login module to log into Geronimo.

Implementation of the GeronimoLoginConfiguration.getAppConfigurationEntry(String app-name) finds implementation of the ConfigurationEntryFactory with the same name as input argument and retrieves corresponding JaasLoginModuleConfiguration with the call to generateConfiguration(). It then wraps the JaasLoginModuleConfiguration into one-element array of the AppConfigurationEntry type and returns it to the caller.

AppConfigurationEntry is injected with the login module from the JaasLoginModuleConfiguration that is created by the implementation of the ConfigurationEntryFactory. If you want to log into Geronimo, this login module must be a special login module (JaasLoginCoordinator, see the JaasLoginService API Discussion section). It is flagged as REQUIRED. Here JAAS becomes a trivial wrapper, JAAS-compatible login module combination semantics is implemented by the JaasLoginCoordinator.

Also note that the names of the ConfigurationEntryFactories map to the JAAS app-name that is passed to the JAAS LoginContext constructor.

ConfigurationEntryFactory implementations

There are several implementations of the ConfigurationEntryFactory interface in Geronimo:

org.apache.geronimo.security.jaas.DirectConfigurationEntry

org.apache.geronimo.security.jaas.ServerRealmConfigurationEntry

org.apache.geronimo.security.realm.GenericSecurityRealm

The most simple is the DirectConfigurationEntry class. It exposes one login module to the clients without any intervention from Geronimo. It is injected with the application-name, login-module, and control flag. Note that if you wire up any old login module in here you will not be able to log into Geronimo. Use this class if you want to have (possibly) different names for the application configuration name and security realm name.

ServerRealmConfigurationEntry is a helper class that simplifies wiring of the server-side component (such as a servlet) to the security realm. This class is injected with the application-configuration name, realm name, and JaasLoginService reference. It uses special login module JaasLoginCoordinator in it's configuration. JaasLoginCoordinator represents a client in the authentication protocol that is enforcing consistent access to the JaasLoginService (and ultimately to the security realm) during authentication procedure. Use this class if you want to have (possibly) different names for the application configuration name and security realm name.

GenericSecurityRealm implements 2 interfaces: ConfigurationEntryFactory and SecurityRealm. As far as the ConfigurationEntryFactory interface is concerned, JaasLoginCoordinator is compiled in this class as a login module that is injected into JaasLoginModuleConfiguration. If you use this class, application configuration name is always the same as the realm name. The use of this class is recommended in most cases.