The target of this article is to provide a JAAS configuration for LDAP authentication using either OpenLDAP or Apache Directory Server and then programatically use this authentication mechanism.
LDAP Configuration
This article assumes you already have an LDAP configured. If not you cand either use the basic configuration from Apache Directory Studio or check the detailed steps here (appliable for OpenLDAP on Ubuntu 9.10).
Configuring for OpenLDAP
Assuming your LDAP structure is similar to the one in the image bellow:
You need to configure an authentication policy in $JBOSS_HOME/server/defautl/conf/login-config.xml as follows:
<application-policy name="example">
<authentication>
<login-module code="org.jboss.security.auth.spi.LdapExtLoginModule" flag="required" >
<module-option name="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory</module-option>
<module-option name="java.naming.provider.url">ldap://localhost:389</module-option>
<module-option name="java.naming.security.authentication">simple</module-option>
<module-option name="bindDN">cn=admin,dc=example,dc=com</module-option>
<module-option name="bindCredential">secret</module-option>
<module-option name="baseCtxDN">ou=People,dc=example,dc=com</module-option>
<module-option name="baseFilter">(uid={0})</module-option>
<module-option name="rolesCtxDN">ou=Roles,dc=example,dc=com</module-option>
<module-option name="roleFilter">(member={1})</module-option>
<module-option name="roleAttributeID">cn</module-option>
<module-option name="searchScope">ONELEVEL_SCOPE</module-option>
<module-option name="allowEmptyPasswords">true</module-option>
</login-module>
</authentication>
JAAS Code
In order to acces and use the defined policy a code similar to the following can be used:
protected void doLogin(String user, String pass) {
try {
CallbackHandler handler = new UserPassHandler(user, pass);
LoginContext lc = new LoginContext("example", handler);
lc.login();
} catch (Exception e) {
log.info("Login failed", e);
}
return null;
}
class UserPassHandler implements CallbackHandler {
private String user, pass;
private UserPassHandler(String user, String pass) {
super();
this.user = user;
this.pass = pass;
}
public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
for (int i = 0; i < callbacks.length; i++) {
if (callbacks[i] instanceof NameCallback) {
NameCallback nc = (NameCallback) callbacks[i];
nc.setName(user);
} else if (callbacks[i] instanceof PasswordCallback) {
PasswordCallback pc = (PasswordCallback) callbacks[i];
pc.setPassword(pass.toCharArray());
} else {
throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
}
}
}
}
Apache Directory
In the case Apache Directory is used the structure will be similar to the one in the image bellow:
The corresponding configuration will be:
<application-policy name="example">
<authentication>
<login-module code="org.jboss.security.auth.spi.LdapExtLoginModule" flag="required" >
<module-option name="java.naming.factory.initial">com.sun.jndi.ldap.LdapCtxFactory</module-option>
<module-option name="java.naming.provider.url">ldap://localhost:10389</module-option>
<module-option name="java.naming.security.authentication">simple</module-option>
<module-option name="bindDN">uid=admin,ou=system</module-option>
<module-option name="bindCredential">secret</module-option>
<module-option name="baseCtxDN">ou=People,dc=example,dc=com</module-option>
<module-option name="baseFilter">(uid={0})</module-option>
<module-option name="rolesCtxDN">ou=Roles,dc=example,dc=com</module-option>
<module-option name="roleFilter">(member={1})</module-option>
<module-option name="roleAttributeID">cn</module-option>
<module-option name="searchScope">ONELEVEL_SCOPE</module-option>
<module-option name="allowEmptyPasswords">true</module-option>
</login-module>
</authentication>
</application-policy>
Further readings
- The complete article
- More configuration examples including Active Directory
Comments