|
@@ -20,6 +20,11 @@ import org.springframework.dao.IncorrectResultSizeDataAccessException;
|
|
|
|
|
|
import org.springframework.util.Assert;
|
|
|
import org.springframework.util.StringUtils;
|
|
|
+import org.springframework.ldap.ContextSource;
|
|
|
+import org.springframework.ldap.ContextExecutor;
|
|
|
+import org.springframework.ldap.ContextMapper;
|
|
|
+import org.springframework.ldap.support.DirContextAdapter;
|
|
|
+import org.springframework.ldap.support.DistinguishedName;
|
|
|
|
|
|
import java.util.HashSet;
|
|
|
import java.util.Set;
|
|
@@ -36,52 +41,35 @@ import javax.naming.directory.SearchResult;
|
|
|
|
|
|
|
|
|
/**
|
|
|
- * LDAP equivalent of the Spring JdbcTemplate class.<p>This is mainly intended to simplify Ldap access within Acegi
|
|
|
- * Security's LDAP-related services.</p>
|
|
|
+ * 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 Luke Taylor
|
|
|
*/
|
|
|
-public class LdapTemplate {
|
|
|
+public class LdapTemplate extends org.springframework.ldap.LdapTemplate {
|
|
|
//~ Static fields/initializers =====================================================================================
|
|
|
|
|
|
public static final String[] NO_ATTRS = new String[0];
|
|
|
|
|
|
//~ Instance fields ================================================================================================
|
|
|
|
|
|
- private InitialDirContextFactory dirContextFactory;
|
|
|
private NamingExceptionTranslator exceptionTranslator = new LdapExceptionTranslator();
|
|
|
|
|
|
/** Default search controls */
|
|
|
private SearchControls searchControls = new SearchControls();
|
|
|
- private String password = null;
|
|
|
- private String principalDn = null;
|
|
|
|
|
|
//~ Constructors ===================================================================================================
|
|
|
|
|
|
- public LdapTemplate(InitialDirContextFactory dirContextFactory) {
|
|
|
- Assert.notNull(dirContextFactory, "An InitialDirContextFactory is required");
|
|
|
- this.dirContextFactory = dirContextFactory;
|
|
|
+ public LdapTemplate(ContextSource contextSource) {
|
|
|
+ Assert.notNull(contextSource, "ContextSource cannot be null");
|
|
|
+ setContextSource(contextSource);
|
|
|
|
|
|
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- *
|
|
|
- * @param dirContextFactory the source of DirContexts
|
|
|
- * @param userDn the user name to authenticate as when obtaining new contexts
|
|
|
- * @param password the user's password
|
|
|
- */
|
|
|
- public LdapTemplate(InitialDirContextFactory dirContextFactory, String userDn, String password) {
|
|
|
- this(dirContextFactory);
|
|
|
-
|
|
|
- Assert.hasLength(userDn, "userDn must not be null or empty");
|
|
|
- Assert.notNull(password, "password cannot be null");
|
|
|
-
|
|
|
- this.principalDn = userDn;
|
|
|
- this.password = password;
|
|
|
- }
|
|
|
-
|
|
|
//~ Methods ========================================================================================================
|
|
|
|
|
|
/**
|
|
@@ -96,9 +84,9 @@ public class LdapTemplate {
|
|
|
public boolean compare(final String dn, final String attributeName, final Object value) {
|
|
|
final String comparisonFilter = "(" + attributeName + "={0})";
|
|
|
|
|
|
- class LdapCompareCallback implements LdapCallback {
|
|
|
- public Object doInDirContext(DirContext ctx)
|
|
|
- throws NamingException {
|
|
|
+ class LdapCompareCallback implements ContextExecutor {
|
|
|
+
|
|
|
+ public Object executeWithContext(DirContext ctx) throws NamingException {
|
|
|
SearchControls ctls = new SearchControls();
|
|
|
ctls.setReturningAttributes(NO_ATTRS);
|
|
|
ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
|
|
@@ -111,30 +99,28 @@ public class LdapTemplate {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- Boolean matches = (Boolean) execute(new LdapCompareCallback());
|
|
|
+ Boolean matches = (Boolean) executeReadOnly(new LdapCompareCallback());
|
|
|
|
|
|
return matches.booleanValue();
|
|
|
}
|
|
|
|
|
|
- public Object execute(LdapCallback callback) throws DataAccessException {
|
|
|
- DirContext ctx = null;
|
|
|
-
|
|
|
- try {
|
|
|
- ctx = (principalDn == null) ? dirContextFactory.newInitialDirContext()
|
|
|
- : dirContextFactory.newInitialDirContext(principalDn, password);
|
|
|
-
|
|
|
- return callback.doInDirContext(ctx);
|
|
|
- } catch (NamingException exception) {
|
|
|
- throw exceptionTranslator.translate("LdapCallback", exception);
|
|
|
- } finally {
|
|
|
- LdapUtils.closeContext(ctx);
|
|
|
- }
|
|
|
- }
|
|
|
+// public Object execute(LdapCallback callback) throws DataAccessException {
|
|
|
+// DirContext ctx = null;
|
|
|
+//
|
|
|
+// try {
|
|
|
+// ctx = dirContextFactory.getReadOnlyContext();
|
|
|
+//
|
|
|
+// return callback.doInDirContext(ctx);
|
|
|
+// } catch (NamingException exception) {
|
|
|
+// throw exceptionTranslator.translate("LdapCallback", exception);
|
|
|
+// } finally {
|
|
|
+// LdapUtils.closeContext(ctx);
|
|
|
+// }
|
|
|
+// }
|
|
|
|
|
|
public boolean nameExists(final String dn) {
|
|
|
- Boolean exists = (Boolean) execute(new LdapCallback() {
|
|
|
- public Object doInDirContext(DirContext ctx)
|
|
|
- throws NamingException {
|
|
|
+ Boolean exists = (Boolean) executeReadOnly(new ContextExecutor() {
|
|
|
+ public Object executeWithContext(DirContext ctx) throws NamingException {
|
|
|
try {
|
|
|
Object obj = ctx.lookup(LdapUtils.getRelativeName(dn, ctx));
|
|
|
if (obj instanceof Context) {
|
|
@@ -161,12 +147,17 @@ public class LdapTemplate {
|
|
|
*
|
|
|
* @return the object created by the mapper
|
|
|
*/
|
|
|
- public Object retrieveEntry(final String dn, final LdapEntryMapper mapper, final String[] attributesToRetrieve) {
|
|
|
- return execute(new LdapCallback() {
|
|
|
- public Object doInDirContext(DirContext ctx)
|
|
|
- throws NamingException {
|
|
|
- return mapper.mapAttributes(dn,
|
|
|
- ctx.getAttributes(LdapUtils.getRelativeName(dn, ctx), attributesToRetrieve));
|
|
|
+ public Object retrieveEntry(final String dn, final ContextMapper mapper, final String[] attributesToRetrieve) {
|
|
|
+
|
|
|
+ return executeReadOnly(new ContextExecutor() {
|
|
|
+ public Object executeWithContext(DirContext ctx) throws NamingException {
|
|
|
+ Attributes attrs = ctx.getAttributes(LdapUtils.getRelativeName(dn, ctx), attributesToRetrieve);
|
|
|
+
|
|
|
+ // Object object = ctx.lookup(LdapUtils.getRelativeName(dn, ctx));
|
|
|
+
|
|
|
+ DirContextAdapter ctxAdapter = new DirContextAdapter(attrs, new DistinguishedName(dn));
|
|
|
+
|
|
|
+ return mapper.mapFromContext(ctxAdapter);
|
|
|
}
|
|
|
});
|
|
|
}
|
|
@@ -185,8 +176,8 @@ public class LdapTemplate {
|
|
|
*/
|
|
|
public Set searchForSingleAttributeValues(final String base, final String filter, final Object[] params,
|
|
|
final String attributeName) {
|
|
|
- class SingleAttributeSearchCallback implements LdapCallback {
|
|
|
- public Object doInDirContext(DirContext ctx)
|
|
|
+ class SingleAttributeSearchCallback implements ContextExecutor {
|
|
|
+ public Object executeWithContext(DirContext ctx)
|
|
|
throws NamingException {
|
|
|
Set unionOfValues = new HashSet();
|
|
|
|
|
@@ -224,7 +215,7 @@ public class LdapTemplate {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- return (Set) execute(new SingleAttributeSearchCallback());
|
|
|
+ return (Set) executeReadOnly(new SingleAttributeSearchCallback());
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -242,10 +233,12 @@ public class LdapTemplate {
|
|
|
* result.
|
|
|
*/
|
|
|
public Object searchForSingleEntry(final String base, final String filter, final Object[] params,
|
|
|
- final LdapEntryMapper mapper) {
|
|
|
- return execute(new LdapCallback() {
|
|
|
- public Object doInDirContext(DirContext ctx)
|
|
|
+ final ContextMapper mapper) {
|
|
|
+
|
|
|
+ return executeReadOnly(new ContextExecutor() {
|
|
|
+ public Object executeWithContext(DirContext ctx)
|
|
|
throws NamingException {
|
|
|
+
|
|
|
NamingEnumeration results = ctx.search(base, filter, params, searchControls);
|
|
|
|
|
|
if (!results.hasMore()) {
|
|
@@ -274,7 +267,10 @@ public class LdapTemplate {
|
|
|
dn.append(nameInNamespace);
|
|
|
}
|
|
|
|
|
|
- return mapper.mapAttributes(dn.toString(), searchResult.getAttributes());
|
|
|
+ DirContextAdapter ctxAdapter = new DirContextAdapter(
|
|
|
+ searchResult.getAttributes(), new DistinguishedName(dn.toString()));
|
|
|
+
|
|
|
+ return mapper.mapFromContext(ctxAdapter);
|
|
|
}
|
|
|
});
|
|
|
}
|