Authentication and authorization with LDAP

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Authentication and authorization with LDAP

dharma reddy
This post has NOT been accepted by the mailing list yet.
Hi,

I need to authenticate and authorize(user roles) the user. For authorization I am overriding queryForAuthorizationInfo() by extending ActiveDirectoryRealm. When I am authenticating a user, I have to pass ldap complete user path(Ex: cn=test,cn=users,dc=domain,dc=com). Is there any way to only pass userId(Ex:test)?. Can we set like 'ldapRealm.userDnTemplate = cn={0},cn=users,dc=exlab01,dc=com'. Please let me know. Below is the my sample code. My Shiro version 1.3.2

contextFactory = org.apache.shiro.realm.ldap.JndiLdapContextFactory
contextFactory.url = ldap://localhost:389
contextFactory.systemUsername = cn=abc,cn=users,dc=domain,dc=com
contextFactory.systemPassword = test@123
realm = com.sample.test.CustomActiveDirectoryRealm
realm.ldapContextFactory = $contextFactory
realm.searchBase = "dc=domain,dc=com"
realm.groupRolesMap = "CN=Admin,OU=Group,DC=domain,DC=com":"Admin"


package com.sample.test;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.config.IniSecurityManagerFactory;
import org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.Factory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ShiroLDAPTest{

        private static Logger logger = LoggerFactory.getLogger(ShiroLDAPTest.class);
         
    /**
     * @param args
     */
    public static void main(String[] args) {
 
        // Using the IniSecurityManagerFactory, which will use the an INI file
        // as the security file.
        Factory<org.apache.shiro.mgt.SecurityManager> factory =
            new IniSecurityManagerFactory("classpath:customrealm.ini");
 
        // Setting up the SecurityManager...
        org.apache.shiro.mgt.SecurityManager securityManager = factory.getInstance();
        SecurityUtils.setSecurityManager(securityManager);
 
        Subject user = SecurityUtils.getSubject();

        logger.info("User is authenticated:  " + user.isAuthenticated());
 
        UsernamePasswordToken token =
                new UsernamePasswordToken(
                    "cn=test,cn=users,dc=domain,dc=com", "test@123");
 
        user.login(token);
        token.setRememberMe(true);
        logger.info("User is authenticated:  " + user.isAuthenticated());
        logger.info("User hasRole:  " + user.hasRole("Admin"));
        //logger.info("User permission:  " + user.isPermitted("Admin"));
    }
}


package com.sample.test;

import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.Set;

import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.directory.Attribute;
import javax.naming.directory.Attributes;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.LdapContext;

import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.activedirectory.ActiveDirectoryRealm;
import org.apache.shiro.realm.ldap.LdapContextFactory;
import org.apache.shiro.realm.ldap.LdapUtils;
import org.apache.shiro.subject.PrincipalCollection;

public class CustomActiveDirectoryRealm extends ActiveDirectoryRealm {

        @Override
    protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException {
        String username = (String) getAvailablePrincipal(principals);

        // Perform context search
        LdapContext ldapContext = ldapContextFactory.getSystemLdapContext();

        Set<String> roleNames = null;

        try {
            roleNames = getRoleNamesForUser(username, ldapContext);

        } finally {
            LdapUtils.closeContext(ldapContext);
        }

        return buildAuthorizationInfo(roleNames);
    }

    // Customize your search query here
    //private static final String USER_SEARCH_FILTER = "(&(objectClass=*)(sn={0}))";
        //(&(objectClass=user)(sAMAccountName=yourUserName) (memberof=CN=YourGroup,OU=Users,DC=YourDomain,DC=com))

    private Set<String> getRoleNamesForUser(String username, LdapContext ldapContext) throws NamingException {
    String searchFilter ="(&(objectClass=*)(cn=test))";
        Set<String> roleNames;
        roleNames = new LinkedHashSet<String>();

        SearchControls searchCtls = new SearchControls();
        searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE);

        String userPrincipalName = username.replace("acegas\\", "");
        if (principalSuffix != null) {
            userPrincipalName += principalSuffix;
        }

        Object[] searchArguments = new Object[]{userPrincipalName};

        NamingEnumeration answer = ldapContext.search(searchBase, searchFilter, searchArguments, searchCtls);

        while (answer.hasMoreElements()) {
            SearchResult sr = (SearchResult) answer.next();

            Attributes attrs = sr.getAttributes();
            if (attrs != null) {
                NamingEnumeration ae = attrs.getAll();
                while (ae.hasMore()) {
                    Attribute attr = (Attribute) ae.next();
                    if (attr.getID().equals("memberOf")) {
                        Collection<String> groupNames = LdapUtils.getAllAttributeValues(attr);
                        System.out.println("groupNames:"+groupNames);
                        Collection<String> rolesForGroups = getRoleNamesForGroups(groupNames);
                        roleNames.addAll(rolesForGroups);
                    }
                }
            }
        }
        return roleNames;
    }
}