|
|
|
@ -19,12 +19,22 @@ import javax.naming.NamingException; |
|
|
|
import javax.naming.NamingEnumeration; |
|
|
|
import javax.naming.NamingEnumeration; |
|
|
|
import javax.naming.directory.DirContext; |
|
|
|
import javax.naming.directory.DirContext; |
|
|
|
import javax.naming.directory.SearchControls; |
|
|
|
import javax.naming.directory.SearchControls; |
|
|
|
|
|
|
|
import javax.naming.directory.SearchResult; |
|
|
|
|
|
|
|
import javax.naming.directory.Attributes; |
|
|
|
|
|
|
|
import javax.naming.directory.Attribute; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.dao.DataAccessException; |
|
|
|
import org.springframework.dao.DataAccessException; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
import org.springframework.util.Assert; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import java.util.Set; |
|
|
|
|
|
|
|
import java.util.HashSet; |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* LDAP equivalent of the Spring JdbcTemplate class. |
|
|
|
* LDAP equivalent of the Spring JdbcTemplate class. |
|
|
|
|
|
|
|
* <p> |
|
|
|
|
|
|
|
* This is mainly intended to simplify Ldap access within Acegi Security's |
|
|
|
|
|
|
|
* LDAP-related services. |
|
|
|
|
|
|
|
* </p> |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Ben Alex |
|
|
|
* @author Ben Alex |
|
|
|
* @author Luke Taylor |
|
|
|
* @author Luke Taylor |
|
|
|
@ -36,6 +46,8 @@ public class LdapTemplate { |
|
|
|
private InitialDirContextFactory dirContextFactory; |
|
|
|
private InitialDirContextFactory dirContextFactory; |
|
|
|
private String userDn = null; |
|
|
|
private String userDn = null; |
|
|
|
private String password = null; |
|
|
|
private String password = null; |
|
|
|
|
|
|
|
/** Default search scope */ |
|
|
|
|
|
|
|
private int searchScope = SearchControls.SUBTREE_SCOPE; |
|
|
|
|
|
|
|
|
|
|
|
public LdapTemplate(InitialDirContextFactory dirContextFactory) { |
|
|
|
public LdapTemplate(InitialDirContextFactory dirContextFactory) { |
|
|
|
Assert.notNull(dirContextFactory, "An InitialDirContextFactory is required"); |
|
|
|
Assert.notNull(dirContextFactory, "An InitialDirContextFactory is required"); |
|
|
|
@ -52,6 +64,10 @@ public class LdapTemplate { |
|
|
|
this.password = password; |
|
|
|
this.password = password; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public void setSearchScope(int searchScope) { |
|
|
|
|
|
|
|
this.searchScope = searchScope; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public Object execute(LdapCallback callback) throws DataAccessException { |
|
|
|
public Object execute(LdapCallback callback) throws DataAccessException { |
|
|
|
DirContext ctx = null; |
|
|
|
DirContext ctx = null; |
|
|
|
|
|
|
|
|
|
|
|
@ -93,4 +109,57 @@ public class LdapTemplate { |
|
|
|
|
|
|
|
|
|
|
|
return matches.booleanValue(); |
|
|
|
return matches.booleanValue(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
|
|
* Performs a search using the supplied filter and returns the union of the values of the named |
|
|
|
|
|
|
|
* attribute found in all entries matched by the search. Note that one directory entry may have several |
|
|
|
|
|
|
|
* values for the attribute. |
|
|
|
|
|
|
|
* |
|
|
|
|
|
|
|
* @param base the DN to search in |
|
|
|
|
|
|
|
* @param filter search filter to use |
|
|
|
|
|
|
|
* @param params the parameters to substitute in the search filter |
|
|
|
|
|
|
|
* @param attributeName the attribute who's values are to be retrieved. |
|
|
|
|
|
|
|
* @return the set of values for the attribute as a union of the values found in all the matching entries. |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
public Set searchForSingleAttributeValues(final String base, final String filter, final Object[] params, final String attributeName) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LdapSearchCallback implements LdapCallback { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public Object execute(DirContext ctx) throws NamingException { |
|
|
|
|
|
|
|
Set unionOfValues = new HashSet(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SearchControls ctls = new SearchControls(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ctls.setSearchScope(searchScope); |
|
|
|
|
|
|
|
ctls.setReturningAttributes(new String[] {attributeName}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NamingEnumeration matchingEntries = |
|
|
|
|
|
|
|
ctx.search(base, filter, params, ctls); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while (matchingEntries.hasMore()) { |
|
|
|
|
|
|
|
SearchResult result = (SearchResult) matchingEntries.next(); |
|
|
|
|
|
|
|
Attributes attrs = result.getAttributes(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// There should only be one attribute in each matching entry.
|
|
|
|
|
|
|
|
NamingEnumeration returnedAttributes = attrs.getAll(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while(returnedAttributes.hasMore()) { |
|
|
|
|
|
|
|
Attribute returnedAttribute = (Attribute) returnedAttributes.next(); |
|
|
|
|
|
|
|
NamingEnumeration attributeValues = returnedAttribute.getAll(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while(attributeValues.hasMore()) { |
|
|
|
|
|
|
|
Object value = attributeValues.next(); |
|
|
|
|
|
|
|
unionOfValues.add(value); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return unionOfValues; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (Set)execute(new LdapSearchCallback()); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|