1
votes

I am trying to configure apache shiro to authenticate using our LDAP server. I am not very familiar with LDAP so forgive my ignorance please!

Using the following option in shiro.ini is working ok (users are authenticated):

ldapRealm.userDnTemplate = uid={0},ou=users,dc=mycompany,dc=com

However we have more than one organization unit (ou) in our company. How can I make the ou parameter take multiple values ? Can I use something this

ldapRealm.userDnTemplate = uid={0},ou=*,dc=mycompany,dc=com

I just want to try all organization units until the login is successfull.

What about adding extra ldap realms having different ou like this:

#ldapRealm1
ldapRealm1 = org.apache.shiro.realm.ldap.JndiLdapRealm
ldapRealm1.userDnTemplate = uid={0},ou=users1,dc=mycompany,dc=com
ldapRealm1.contextFactory.url = ldap://test.com:389
#ldapRealm2
ldapRealm2 = org.apache.shiro.realm.ldap.JndiLdapRealm
ldapRealm2.userDnTemplate = uid={0},ou=users2,dc=mycompany,dc=com
ldapRealm2.contextFactory.url = ldap://test.com:389
#ldapRealm3
ldapRealm3 = org.apache.shiro.realm.ldap.JndiLdapRealm
ldapRealm3.userDnTemplate = uid={0},ou=users3,dc=mycompany,dc=com
ldapRealm3.contextFactory.url = ldap://test.com:389

Will this work ?

Also is it possible to add a dropdown in the login page to allow the users select their organization unit and pass it as a paremeter to the ldapRealm ? How should I proceed with that ?

TIA, Serafeim

1

1 Answers

1
votes

Multiple realms will work just fine. You'll just need to create a sub-interface of AuthenticationToken that also specifies which Organizational Unit you are targeting.

Then you can create a subclass of LdapRealm and change the supports() method to return true IFF the AuthenticationToken reflects the targeted Organizational Unit. For example:

LdapAuthenticationToken extends AuthenticationToken {
    String getOrganizationalUnit();
}

LdapUsernamePasswordToken extends UsernamePasswordToken 
    implements LdapAuthenticationToken  {
    private String organizationalUnit; //add getter/setter
}

MyLdapRealm extends LdapRealm {
    private String organizationalUnit; //add getter/setter
    @Override
    public boolean supports(AuthenticationToken token) {
        return token != null && token instanceof LdapAuthenticationToken &&
            this.organizationalUnit.equals(
                ((LdapAuthenticationToken)token).getOrganizationalUnit());
    }

    @Override
    protected AuthenticationInfo doGetAuthenticatinoInfo(AuthenticationToken token) {
        LdapAuthenticationToken ldapToken = (LdapAuthenticationToken)token;
        //get the OU here, and do whatever you want with it.
    }
}

If you have more than one realm, be aware that each will probably have its own LDAP connection pool which may not be as efficient as a single shared connection pool.

If you want to have a single connection pool, you'll need to use one realm and manually formulate queries based on the OrganizationalUnit. The LdapAuthenticationToken would be helpful in this case too.