| Name | Crowd JAAS Login Module |
|---|---|
| Version | 0.9.2 |
| Product Versions | Crowd 1.0.6 |
| Author(s) | Brad Harvey |
| Homepage | |
| Price | Free |
| License | BSD |
| JavaDocs | |
| IssueTracking | |
| Download JAR | CrowdJaasLoginModule-0.9.2.jar |
| Download Source | CrowdJaasLoginModule-0.9.2-src.zip |
The JAAS Login Module is a Crowd Application Connector for JAAS and Spring Acegi.
Description/Features
Plug straight in to existing applications that use JAAS to take full advantage of Crowd's application provisioning and identity management features.
Enable single sign on in applications using the Spring Acegi security framework.
Usage
JAAS Login Module Options
The Crowd JAAS Login Module is configured via module options. These are set in an application specific manner (often with a Configuration file).
The options you need to set are:
- crowd.server.url
- application.name
- application.password
This will allow you to authenticate against crowd with a user/password and retrieve the user's Crowd groups. These options can be set in the login module configuration, or in a crowd.properties file on the classpath. The remaining options must be set in the login module configuration.
If you want to authenticate with a token instead of password, set useToken.
| Module Option | Description | Default |
|---|---|---|
| crowd.server.url | URL to Crowd web service | Defaulted from crowd.properties file |
| application.name | Crowd application name | Defaulted from crowd.properties file |
| application.password | Crowd application password | Defaulted from crowd.properties file |
| useToken | if true, treat the password as a token | false |
If you are chaining login modules, tryFirstPass and friends can be used to share state between them. This is used where interactive callback handlers are employed to prevent the user being asked for their password multiple times.
| Module Option | Description | Default |
|---|---|---|
| storePass | if true, save shared state if login succeeds (tryFirstPass and useFirstPass do not enable this automatically). | false |
| tryFirstPass | if true, attempt authentication from shared state. If this fails, try again with callback handler. | false |
| useFirstPass | if true, only attempt authentication from shared state - do not use callbackhandler at all. | false |
| clearPass | if true, clear shared state after commit | false |
| storeToken | if true and storePass is true, save the token to shared state instead of the password. Automatically true if useToken is true. | useToken ? true : false |
Finally, if you need specific classes for principals and groups they can be specified with principalClassName and friends.
| Module Option | Description | Default |
|---|---|---|
| principalClassName | class name of Principal implementation for User Principal | com.atlassian.crowd.application.jaas.CrowdPrincipal |
| roleGroupClassName | class name of Group implementation to contain roles | com.atlassian.crowd.application.jaas.CrowdGroup |
| roleGroupName | name of role Group | Roles |
| roleClassName | class name of Principal implementation for role Principals within the role group | value of principalClassName |
JAAS in Acegi
See Acegi JAAS for instructions on using a JAAS login module in Acegi. Essentially, you need to configure the login module in a JaasAuthenticationProvider, and provide com.atlassian.crowd.application.acegi.CrowdAuthorityGranter as the AuthorityGranter to return the Crowd groups as granted authorities to Acegi.
<bean id="jaasAuthenticationProvider" class="org.acegisecurity.providers.jaas.JaasAuthenticationProvider"> <property name="loginConfig"> <value>/WEB-INF/login.conf</value> </property> <property name="loginContextName"> <value>crowd</value> </property> <property name="callbackHandlers"> <list> <bean class="org.acegisecurity.providers.jaas.JaasNameCallbackHandler"/> <bean class="org.acegisecurity.providers.jaas.JaasPasswordCallbackHandler"/> </list> </property> <property name="authorityGranters"> <list> <bean class="com.atlassian.crowd.application.acegi.CrowdAuthorityGranter"/> </list> </property> </bean>
The login config should look something like this:
crowd {
com.atlassian.crowd.application.jaas.CrowdLoginModule required application.name=acegi application.password=acegi crowd.server.url="http://localhost:8095/crowd/services/";
};
|
If your environment already uses JAAS, the loginConfig property may be ignored in favour of that environment's configuration mechanism. For example, in JBoss the login module has to be configured in conf/login-config.xml |
Acegi Single Sign On
Single Sign On is implemented using the RememberMe infrastructure. It does not actually store the token information persistently for true remember me, and is not intended to.
The RememberMeServices implementation is com.atlassian.crowd.application.acegi.CrowdVerifyTokenService. This reads a crowd.properties file from the classpath (see Java Integration Libraries).
<bean id="rememberMeServices" class="com.atlassian.crowd.application.acegi.CrowdVerifyTokenService"> <constructor-arg value="changeThis"/> <!-- key must be shared with RememberMeAuthenticationProvider --> </bean>
Place this snippet inside your authentication provider. The key must be shared with the rememberMeServices, but it isn't actually used to validate the cookie - Crowd has already validated it in the CrowdVerifyTokenService.
<bean class="org.acegisecurity.providers.rememberme.RememberMeAuthenticationProvider"> <property name="key" value="changeThis"/> </bean>
You will also need to add rememberMeServices references to various other beans. Here are the applicable beans in the acegi-tutorial configuration.
<!-- add remember me references to various other beans as per normal --> <bean id="logoutFilter" class="org.acegisecurity.ui.logout.LogoutFilter"> <constructor-arg value="/index.jsp"/> <!-- URL redirected to after logout --> <constructor-arg> <list> <ref bean="rememberMeServices"/> <bean class="org.acegisecurity.ui.logout.SecurityContextLogoutHandler"/> </list> </constructor-arg> </bean> <bean id="authenticationProcessingFilter" class="org.acegisecurity.ui.webapp.AuthenticationProcessingFilter"> <property name="authenticationManager" ref="authenticationManager"/> <property name="authenticationFailureUrl" value="/acegilogin.jsp?login_error=1"/> <property name="defaultTargetUrl" value="/"/> <property name="filterProcessesUrl" value="/j_acegi_security_check"/> <property name="rememberMeServices" ref="rememberMeServices"/> </bean> <bean id="rememberMeProcessingFilter" class="org.acegisecurity.ui.rememberme.RememberMeProcessingFilter"> <property name="authenticationManager" ref="authenticationManager"/> <property name="rememberMeServices" ref="rememberMeServices"/> </bean>
Examples
Simple JAAS Client
Here's a sample client. I created an application in Crowd called soapui with a password of soapui. This JAAS module configuration sets the application name, password, and Crowd server url.
Crowd {
com.atlassian.crowd.application.jaas.CrowdLoginModule required application.name=soapui application.password=soapui crowd.server.url="http://localhost:8095/crowd/services/";
};
Here's a snippet of code to load this configuration file from the classpath, create a login context, and login.
URL resource = Thread.currentThread().getContextClassLoader().getResource("crowd.conf"); System.setProperty("java.security.auth.login.config", URLDecoder.decode(resource.getFile())); LoginContext loginContext = new LoginContext("Crowd", new UsernamePasswordCallbackHandler("testuser", "password".toCharArray())); loginContext.login(); System.out.println(loginContext.getSubject()); loginContext.logout();
The UsernamePasswordCallbackHandler class is in the test directory of the source distribution. The output of that snippet is:
Subject: Principal: CrowdGroup: Roles [CrowdPrincipal: crowd-administrators, CrowdPrincipal: soapui] Principal: CrowdPrincipal: testuser
The user "testuser" has crowd-administrators and soapui groups in Crowd.
JBoss Login Module
To use the CrowdJAASLoginModule in JBoss, you need to change login-config.xml and copy the jar and dependencies into the server lib directory. I have tested with JBoss 4.05GA and JDK 1.5.
Here's an example application policy entry in login-config.xml. Adjust the module options as required.
<application-policy name = "jmx-console"> <authentication> <login-module code="com.atlassian.crowd.application.jaas.CrowdLoginModule" flag = "required"> <module-option name="application.name">jboss</module-option> <module-option name="application.password">jboss</module-option> <module-option name="crowd.server.url">http://localhost:8095/crowd/services/</module-option> </login-module> </authentication> </application-policy>
In addition to CrowdJaasLoginModule-0.9.2.jar, the following jars are required in the <jboss home>/server/<context>/lib directory (eg, C:\jboss-4.0.5.GA\server\default\lib). All can be found in the client and client/lib directory under your Crowd installation.
- crowd-core-1.0.6.jar
- xfire-all-1.2.1.jar
- stax-api-1.0.1.jar
- wstx-asl-2.9.3.jar
- jdom-1.0.jar
- commons-httpclient-3.0.jar
This directory already contains a commons-httpclient.jar - this should be removed.
Sample Application
The Application Launchpad uses the JAAS and Acegi single sign on capabilities of the Crowd JAAS Login Module.
Version History
| Version | Release Date | Description |
|---|---|---|
| 0.9.2 | April 29, 2007 | Add Acegi support - see release notes in CrowdJaasLoginModule-0.9.2-src.zip |
| 0.9.1 | April 26, 2007 | Minor bug fix and enhancement - see release notes in CrowdJaasLoginModule-0.9.1.zip |
| 0.9 | April 25, 2007 | Initial Version. |
Dependencies
- Should be the same as the normal java integration client - crowd-core + jars found in $CROWD_INSTALL/client/lib.
- I had to use xerces 2.8.1 to fix a class not found error.
- The maven2 transitive dependencies report is quite scary due to xfire-all.
Known Limitations
The Crowd JAAS Login module uses the SecurityServerClient to communicate with Crowd. This class is implemented in a static manner, which means if you have multiple login modules defined they all share the same details for connecting to Crowd. This may not be suitable in a server environment.
Crowd roles and user attributes are not retrieved by the login module. In theory these could be retrieved and added to the subject as well.
The clearPass option will clear shared state added by other modules.
Logging out doesn't actually invalidate the token. In a single sign on environment this is probably a feature ![]()
Building from Source
This project uses maven2. I use the maven2 plugin for eclipse - http://m2eclipse.codehaus.org/.
You may need to add crowd-core to your local repository. Change to the $CROWD_INSTALL/client directory and execute this command:
mvn install:install-file -DgroupId=com.atlassian.crowd -DartifactId=crowd-core -Dversion=1.0.6 -Dpackaging=jar -Dfile=crowd-core-1.0.6.jar
References
JAAS Documentation
Acegi
