JBoss at Work: A Practical Guide
9.5. Deploying a JAAS-Based Security Realm on JBoss
There is no standard for integrating JAAS deployment with a J2EE application server, so each server has its own way to set up LoginModule configuration and domain names. So, we need to:
9.5.1. JBoss LoginModule Configuration
To Configure a LoginModule in JBoss, you have a couple of options.
9.5.2. Custom LoginModule Configuration
We chose to create our own separate LoginModule Configuration file, jaw-login-config.xml, because we didn't want to co-mingle our application-specific JAAS LoginModule configuration with JBoss-internal LoginModule settings. Co-mingling LoginModule settings is bad because each time you upgrade to a new version of JBoss, you have to re-add your <application-policy> elements to the default login-config.xml file to make things work again. To deploy the LoginModule configuration file to JBoss, the Ant build script copies the jaw-login-config.xml file from the ch09-a/src/META-INF directory to the JBoss configuration directory$JBOSS_HOME/server/default/conf. The jaw-login-config.xml file in Example 9-5 looks just like the JBoss default login-config.xml, but our file contains only application-specific <application-policy> elements. Example 9-5. jaw-login-config.xml
<?xml version='1.0'?> <!DOCTYPE policy PUBLIC "-//JBoss//DTD JBOSS Security Config 3.0//EN" "http://www.jboss.org/j2ee/dtd/security_config.dtd"> <policy> <application-policy name = "JawJaasDbRealm"> <authentication> <login-module code = "org.jboss.security.auth.spi.DatabaseServerLoginModule" flag = "required"> <module-option name="unauthenticatedIdentity">guest</module-option> <module-option name="password-stacking">useFirstPass</module-option> <module-option name="dsJndiName">java:/JBossAtWorkDS</module-option> <module-option name="principalsQuery">SELECT PASSWORD FROM USER WHERE NAME=? </module-option> <module-option name="rolesQuery">SELECT ROLE.NAME, 'Roles' FROM ROLE, USER_ROLE, USER WHERE USER.NAME=? AND USER.ID=USER_ROLE.USER_ID AND ROLE.ID = USER_ROLE.USER_ID</module-option> </login-module> </authentication> </application-policy> </policy> JBoss uses an MBean that reads the $JBOSS_HOME/server/default/conf/jaw-login-config.xml file at startup time to configure its security domains. Each <application-policy> element configures a LoginModule for a security realm. The name attribute sets the JAAS application name to "JawJaasDbRealm". The <login-module> element configures the JBoss-specific DatabaseServerLoginModule to query the USER and ROLE tables in the JAW Motors database to authenticate the user. The <login-module> element's flag attribute is set to required because we don't want to allow the user to access sensitive portions of the JAW Motors application unless she successfully logs on to all the security realms. The <module-option> elements for the DatabaseServerLoginModule specify LoginModule options (JAAS-speak for initialization parameters):
Since the JAW Motor's application-specific LoginModule configuration file is not part of the default JBoss setup anymore, we need to tell JBoss to load this file at startup time. To do this, we create a JMX MBean defined in a service filejaw-login-config-service.xml (see Example 9-6). Example 9-6. jaw-login-config-service.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE server> <server> <mbean code="org.jboss.security.auth.login.DynamicLoginConfig" name="jboss:service=DynamicLoginConfig"> <attribute name="AuthConfig">jaw-login-config.xml</attribute> <depends optional-attribute-name="LoginConfigService"> jboss.security:service=XMLLoginConfig </depends> <depends optional-attribute-name="SecurityManagerService"> jboss.security:service=JaasSecurityManager </depends> </mbean> </server>
This service file, courtesy of the JBoss Wiki, configures the DynamicLoginConfig MBean so it uses the JBoss XMLLoginConfig MBean to read the application-specific jaw-login-config.xml and configure our LoginModule. If the DynamicLoginConfig MBean is stopped, the JaasSecurityManager MBean logs out all the LoginModule's users by cleaning out all Subjects (users) and Principals (roles) set by the LoginModule(s) configured in our LoginModule configuration file. For more information on the DynamicLoginConfig MBean, visit the JBoss Wiki at: http://wiki.jboss.org/wiki/Wiki.jsp?page=DynamicLoginConfig. To deploy the MBean service file to JBoss, the Ant build script copies the jaw-login-config-service.xml file from the ch09-a/src/META-INF directory to the JBoss deployment directory$JBOSS_HOME/server/default/deploy. 9.5.3. JAAS Domain Settings in jboss-web.xml
The security domain in jboss-web.xml defines a security domain used by all web components in the application. Later in the chapter we'll extend the security domain to protect the entire application by including EJBs, but we don't have to worry about that right now. The <security-domain> element used in the JBoss-specific jboss-web.xml deployment descriptor must match the "JawJaasDbRealm" JAAS application name from login-config.xml. The <security-domain> element comes before the elements that define the JNDI-based resources. Here's the <security-domain> element in jboss-web.xml (Example 9-7). Example 9-7. jboss-web.xml
<jboss-web> <security-domain>java:/jaas/JawJaasDbRealm</security-domain> ... </jboss-web>
The <security-domain> uses java:/jaas/JawJaasDbRealm because it is the JBoss-specific JNDI name used in jaw-login-config.xml when JBoss deploys the LoginModule as a managed service. The pattern here is that JBoss prefixes its JAAS JNDI names with java:/jaas. 9.5.4. Automating JAAS Domain Settings in jboss-web.xml
If you'll recall from the Web chapter, we used XDoclet's Ant <webdoclet> task and its <jbosswebxml> subtask to respectively generate the J2EE standard web.xml and jboss-web.xml JBoss-specific EJB deployment descriptors. We now add a securitydomain attribute to the <jbosswebxml> subtask in the webapp sub-project's build.xml (Example 9-8) to generate the <security-domain> element in jboss-web.xml. Example 9-8. webapp/build.xml
... <webdoclet> ... <jbosswebxml version="4.0" destdir="${gen.source.dir}" securitydomain="java:/jaas/JawJaasDbRealm"/> </webdoclet> ... |