Version 1

    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:

    http://www.len.ro/photo/daily/work/openldap.png

     

    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:

    http://www.len.ro/photo/daily/work/apacheds.png

     

    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