package com.hwlcn.security.realm.activedirectory; import com.hwlcn.security.authc.AuthenticationInfo; import com.hwlcn.security.authc.AuthenticationToken; import com.hwlcn.security.authc.SimpleAuthenticationInfo; import com.hwlcn.security.authc.UsernamePasswordToken; import com.hwlcn.security.authz.AuthorizationInfo; import com.hwlcn.security.authz.SimpleAuthorizationInfo; import com.hwlcn.security.realm.ldap.AbstractLdapRealm; import com.hwlcn.security.realm.ldap.LdapUtils; import com.hwlcn.security.subject.PrincipalCollection; import com.hwlcn.security.realm.ldap.LdapContextFactory; import org.slf4j.Logger; import org.slf4j.LoggerFactory; 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 java.util.*; public class ActiveDirectoryRealm extends AbstractLdapRealm { private static final Logger log = LoggerFactory.getLogger(ActiveDirectoryRealm.class); private static final String ROLE_NAMES_DELIMETER = ","; private Map<String, String> groupRolesMap; public void setGroupRolesMap(Map<String, String> groupRolesMap) { this.groupRolesMap = groupRolesMap; } protected AuthenticationInfo queryForAuthenticationInfo(AuthenticationToken token, LdapContextFactory ldapContextFactory) throws NamingException { UsernamePasswordToken upToken = (UsernamePasswordToken) token; LdapContext ctx = null; try { ctx = ldapContextFactory.getLdapContext(upToken.getUsername(), String.valueOf(upToken.getPassword())); } finally { LdapUtils.closeContext(ctx); } return buildAuthenticationInfo(upToken.getUsername(), upToken.getPassword()); } protected AuthenticationInfo buildAuthenticationInfo(String username, char[] password) { return new SimpleAuthenticationInfo(username, password, getName()); } protected AuthorizationInfo queryForAuthorizationInfo(PrincipalCollection principals, LdapContextFactory ldapContextFactory) throws NamingException { String username = (String) getAvailablePrincipal(principals); LdapContext ldapContext = ldapContextFactory.getSystemLdapContext(); Set<String> roleNames; try { roleNames = getRoleNamesForUser(username, ldapContext); } finally { LdapUtils.closeContext(ldapContext); } return buildAuthorizationInfo(roleNames); } protected AuthorizationInfo buildAuthorizationInfo(Set<String> roleNames) { return new SimpleAuthorizationInfo(roleNames); } private Set<String> getRoleNamesForUser(String username, LdapContext ldapContext) throws NamingException { Set<String> roleNames; roleNames = new LinkedHashSet<String>(); SearchControls searchCtls = new SearchControls(); searchCtls.setSearchScope(SearchControls.SUBTREE_SCOPE); String userPrincipalName = username; if (principalSuffix != null) { userPrincipalName += principalSuffix; } String searchFilter = "(&(objectClass=*)(userPrincipalName={0}))"; Object[] searchArguments = new Object[]{userPrincipalName}; NamingEnumeration answer = ldapContext.search(searchBase, searchFilter, searchArguments, searchCtls); while (answer.hasMoreElements()) { SearchResult sr = (SearchResult) answer.next(); if (log.isDebugEnabled()) { log.debug("Retrieving group names for user [" + sr.getName() + "]"); } 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); if (log.isDebugEnabled()) { log.debug("Groups found for user [" + username + "]: " + groupNames); } Collection<String> rolesForGroups = getRoleNamesForGroups(groupNames); roleNames.addAll(rolesForGroups); } } } } return roleNames; } protected Collection<String> getRoleNamesForGroups(Collection<String> groupNames) { Set<String> roleNames = new HashSet<String>(groupNames.size()); if (groupRolesMap != null) { for (String groupName : groupNames) { String strRoleNames = groupRolesMap.get(groupName); if (strRoleNames != null) { for (String roleName : strRoleNames.split(ROLE_NAMES_DELIMETER)) { if (log.isDebugEnabled()) { log.debug("User is member of group [" + groupName + "] so adding role [" + roleName + "]"); } roleNames.add(roleName); } } } } return roleNames; } }