Przeglądaj źródła

SEC-513: Ldap user manager implementation classes changed to use new spring ldap apis.

Luke Taylor 18 lat temu
rodzic
commit
6eb17c8546

+ 3 - 2
core/src/main/java/org/acegisecurity/userdetails/ldap/InetOrgPerson.java

@@ -14,8 +14,9 @@
  */
 package org.acegisecurity.userdetails.ldap;
 
-import org.springframework.ldap.support.DirContextOperations;
-import org.springframework.ldap.support.DirContextAdapter;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+
 
 /**
  * UserDetails implementation whose properties are based on a subset of the

+ 2 - 2
core/src/main/java/org/acegisecurity/userdetails/ldap/InetOrgPersonContextMapper.java

@@ -16,8 +16,8 @@ package org.acegisecurity.userdetails.ldap;
 
 import org.acegisecurity.userdetails.UserDetails;
 import org.acegisecurity.GrantedAuthority;
-import org.springframework.ldap.support.DirContextOperations;
-import org.springframework.ldap.support.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.ldap.core.DirContextAdapter;
 import org.springframework.util.Assert;
 
 

+ 1 - 2
core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsImpl.java

@@ -18,8 +18,7 @@ package org.acegisecurity.userdetails.ldap;
 import org.acegisecurity.GrantedAuthority;
 
 import org.springframework.util.Assert;
-import org.springframework.ldap.support.DirContextOperations;
-import org.springframework.ldap.support.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
 
 import java.util.ArrayList;
 import java.util.Arrays;

+ 31 - 18
core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsManager.java

@@ -21,23 +21,34 @@ import org.acegisecurity.ldap.LdapUtils;
 import org.acegisecurity.GrantedAuthority;
 import org.acegisecurity.GrantedAuthorityImpl;
 import org.acegisecurity.Authentication;
+import org.acegisecurity.BadCredentialsException;
 import org.acegisecurity.context.SecurityContextHolder;
 import org.springframework.dao.DataAccessException;
 import org.springframework.util.Assert;
-import org.springframework.ldap.support.DistinguishedName;
-import org.springframework.ldap.support.DirContextAdapter;
-import org.springframework.ldap.LdapTemplate;
-import org.springframework.ldap.AttributesMapper;
-import org.springframework.ldap.ContextSource;
-import org.springframework.ldap.ContextExecutor;
-import org.springframework.ldap.SearchExecutor;
-import org.springframework.ldap.EntryNotFoundException;
+import org.springframework.ldap.core.DistinguishedName;
+import org.springframework.ldap.core.AttributesMapper;
+import org.springframework.ldap.core.LdapTemplate;
+import org.springframework.ldap.core.ContextSource;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.ContextExecutor;
+import org.springframework.ldap.core.SearchExecutor;
+import org.springframework.ldap.core.AttributesMapperCallbackHandler;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
-import javax.naming.*;
 import javax.naming.ldap.LdapContext;
-import javax.naming.directory.*;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.Context;
+import javax.naming.Name;
+import javax.naming.NameNotFoundException;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.SearchControls;
+
 import java.util.*;
 
 /**
@@ -150,9 +161,6 @@ public class LdapUserDetailsManager implements UserDetailsManager {
 
         String username = authentication.getName();
 
-
-
-
         logger.debug("Changing password for user '"+ username);
 
         final DistinguishedName dn = buildDn(username);
@@ -172,7 +180,11 @@ public class LdapUserDetailsManager implements UserDetailsManager {
                 ctx.removeFromEnvironment("com.sun.jndi.ldap.connect.pool");
                 ctx.addToEnvironment(Context.SECURITY_PRINCIPAL, LdapUtils.getFullDn(dn, ctx).toUrl());
                 ctx.addToEnvironment(Context.SECURITY_CREDENTIALS, oldPassword);
-                ctx.reconnect(null);
+                try {
+                    ctx.reconnect(null);
+                } catch (javax.naming.AuthenticationException e) {
+                    throw new BadCredentialsException("Authentication for password change failed.");
+                }
 
                 ctx.modifyAttributes(dn, passwordChange);
 
@@ -199,8 +211,8 @@ public class LdapUserDetailsManager implements UserDetailsManager {
             }
         };
 
-        LdapTemplate.AttributesMapperCallbackHandler roleCollector =
-                template.new AttributesMapperCallbackHandler(roleMapper);
+        AttributesMapperCallbackHandler roleCollector =
+                new AttributesMapperCallbackHandler(roleMapper);
 
         template.search(se, roleCollector);
         List authorities = roleCollector.getList();
@@ -277,7 +289,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
                 LdapUtils.closeContext((Context) obj);
             }
             return true;
-        } catch(EntryNotFoundException e) {
+        } catch(org.springframework.ldap.NameNotFoundException e) {
             return false;
         }
     }
@@ -402,13 +414,14 @@ public class LdapUserDetailsManager implements UserDetailsManager {
 
     /**
      * This class allows us to set the <tt>updateMode</tt> property of DirContextAdapter when updating existing users.
+     * TODO: No longer needed as of Ldap 1.2.
      */
     private static class UserContext extends DirContextAdapter {
         public UserContext(Attributes pAttrs, Name dn) {
             super(pAttrs, dn);
         }
 
-        protected void setUpdateMode(boolean mode) {
+        public void setUpdateMode(boolean mode) {
             super.setUpdateMode(mode);
         }
     }

+ 2 - 7
core/src/main/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsMapper.java

@@ -18,21 +18,16 @@ package org.acegisecurity.userdetails.ldap;
 import org.acegisecurity.GrantedAuthorityImpl;
 import org.acegisecurity.GrantedAuthority;
 
-import org.acegisecurity.ldap.LdapEntryMapper;
-
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 
 import org.springframework.util.Assert;
-import org.springframework.ldap.ContextMapper;
 import org.springframework.ldap.UncategorizedLdapException;
-import org.springframework.ldap.AttributesIntegrityViolationException;
-import org.springframework.ldap.support.DirContextAdapter;
+import org.springframework.ldap.core.ContextMapper;
+import org.springframework.ldap.core.DirContextAdapter;
 
-import javax.naming.NamingEnumeration;
 import javax.naming.NamingException;
 import javax.naming.directory.Attribute;
-import javax.naming.directory.Attributes;
 
 
 /**

+ 5 - 2
core/src/main/java/org/acegisecurity/userdetails/ldap/Person.java

@@ -14,9 +14,12 @@
  */
 package org.acegisecurity.userdetails.ldap;
 
-import org.springframework.ldap.support.DirContextOperations;
-import org.springframework.ldap.support.DirContextAdapter;
+
 import org.springframework.util.Assert;
+
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+
 import org.acegisecurity.ldap.LdapUtils;
 
 import java.util.List;

+ 2 - 2
core/src/main/java/org/acegisecurity/userdetails/ldap/PersonContextMapper.java

@@ -2,8 +2,8 @@ package org.acegisecurity.userdetails.ldap;
 
 import org.acegisecurity.userdetails.UserDetails;
 import org.acegisecurity.GrantedAuthority;
-import org.springframework.ldap.support.DirContextOperations;
-import org.springframework.ldap.support.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.ldap.core.DirContextAdapter;
 import org.springframework.util.Assert;
 
 /**

+ 2 - 2
core/src/main/java/org/acegisecurity/userdetails/ldap/UserDetailsContextMapper.java

@@ -16,8 +16,8 @@ package org.acegisecurity.userdetails.ldap;
 
 import org.acegisecurity.userdetails.UserDetails;
 import org.acegisecurity.GrantedAuthority;
-import org.springframework.ldap.support.DirContextOperations;
-import org.springframework.ldap.support.DirContextAdapter;
+import org.springframework.ldap.core.DirContextOperations;
+import org.springframework.ldap.core.DirContextAdapter;
 
 /**
  * Operations to map a UserDetails object to and from a Spring LDAP <tt>DirContextOperations</tt> implementation.

+ 3 - 2
core/src/test/java/org/acegisecurity/userdetails/ldap/InetOrgPersonTests.java

@@ -1,8 +1,9 @@
 package org.acegisecurity.userdetails.ldap;
 
 import junit.framework.TestCase;
-import org.springframework.ldap.support.DirContextAdapter;
-import org.springframework.ldap.support.DistinguishedName;
+
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DistinguishedName;
 
 /**
  * @author Luke Taylor

+ 44 - 31
core/src/test/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsManagerTests.java

@@ -14,36 +14,32 @@
  */
 package org.acegisecurity.userdetails.ldap;
 
-import org.acegisecurity.ldap.AbstractLdapServerTestCase;
-import org.acegisecurity.ldap.LdapUtils;
+import org.acegisecurity.ldap.SpringSecurityLdapTemplate;
+import org.acegisecurity.ldap.AbstractLdapIntegrationTests;
 import org.acegisecurity.userdetails.UserDetails;
 import org.acegisecurity.userdetails.UsernameNotFoundException;
 import org.acegisecurity.GrantedAuthority;
 import org.acegisecurity.GrantedAuthorityImpl;
+import org.acegisecurity.BadCredentialsException;
 import org.acegisecurity.providers.UsernamePasswordAuthenticationToken;
 import org.acegisecurity.context.SecurityContextHolder;
-import org.springframework.ldap.LdapTemplate;
-import org.springframework.ldap.support.DirContextAdapter;
-import org.springframework.ldap.support.DistinguishedName;
-import org.springframework.dao.DataAccessException;
 
-import javax.naming.directory.DirContext;
-import java.util.List;
-import java.util.Iterator;
+import org.springframework.ldap.core.DirContextAdapter;
 
 /**
  * @author Luke Taylor
  * @version $Id$
  */
-public class LdapUserDetailsManagerTests extends AbstractLdapServerTestCase {
+public class LdapUserDetailsManagerTests extends AbstractLdapIntegrationTests {
     private static final GrantedAuthority[] TEST_AUTHORITIES = new GrantedAuthority[] {new GrantedAuthorityImpl("ROLE_CLOWNS"),
                 new GrantedAuthorityImpl("ROLE_ACROBATS")};
     private LdapUserDetailsManager mgr;
-    private LdapTemplate template;
+    private SpringSecurityLdapTemplate template;
 
-    protected void onSetUp() {
-        mgr = new LdapUserDetailsManager(getInitialCtxFactory());
-        template = new LdapTemplate(getInitialCtxFactory());
+    protected void onSetUp() throws Exception {
+        super.onSetUp();
+        mgr = new LdapUserDetailsManager(getContextSource());
+        template = new SpringSecurityLdapTemplate(getContextSource());
         DirContextAdapter ctx = new DirContextAdapter();
 
         ctx.setAttributeValue("objectclass", "organizationalUnit");
@@ -57,10 +53,11 @@ public class LdapUserDetailsManagerTests extends AbstractLdapServerTestCase {
 
         group.setAttributeValue("objectclass", "groupOfNames");
         group.setAttributeValue("cn", "clowns");
-        template.bind("cn=clowns,ou=testgroups", ctx, null);
+        group.setAttributeValue("member", "cn=nobody,ou=testpeople,dc=acegisecurity,dc=org");
+        template.bind("cn=clowns,ou=testgroups", group, null);
 
         group.setAttributeValue("cn", "acrobats");
-        template.bind("cn=acrobats,ou=testgroups", ctx, null);
+        template.bind("cn=acrobats,ou=testgroups", group, null);
 
         mgr.setUserDnBase("ou=testpeople");
         mgr.setGroupSearchBase("ou=testgroups");
@@ -70,21 +67,20 @@ public class LdapUserDetailsManagerTests extends AbstractLdapServerTestCase {
     }
 
 
-    protected void tearDown() throws Exception {
-        Iterator people = template.list("ou=testpeople").iterator();
+    protected void onTearDown() throws Exception {
+//        Iterator people = template.list("ou=testpeople").iterator();
 
-        DirContext rootCtx = new DirContextAdapter(new DistinguishedName(getInitialCtxFactory().getRootDn()));
+//        DirContext rootCtx = new DirContextAdapter(new DistinguishedName(getInitialCtxFactory().getRootDn()));
+//
+//        while(people.hasNext()) {
+//            template.unbind((String) people.next() + ",ou=testpeople");
+//        }
 
-        while(people.hasNext()) {
-            template.unbind(LdapUtils.getRelativeName((String) people.next(), rootCtx));
-        }
-
-        template.unbind("ou=testpeople");
-        template.unbind("cn=acrobats,ou=testgroups");
-        template.unbind("cn=clowns,ou=testgroups");
-        template.unbind("ou=testgroups");
+        template.unbind("ou=testpeople",true);
+        template.unbind("ou=testgroups",true);
 
         SecurityContextHolder.clearContext();
+        super.onTearDown();
     }
 
     public void testLoadUserByUsernameReturnsCorrectData() {
@@ -154,26 +150,43 @@ public class LdapUserDetailsManagerTests extends AbstractLdapServerTestCase {
         assertEquals(0, mgr.getUserAuthorities(mgr.buildDn("don"), "don").length);
     }
 
-    public void testPasswordChangeSucceeds() {
+    public void testPasswordChangeWithCorrectOldPasswordSucceeds() {
         InetOrgPerson.Essence p = new InetOrgPerson.Essence();
         p.setCn(new String[] {"John Yossarian"});
         p.setSn("Yossarian");
-        p.setUid("john");
+        p.setUid("johnyossarian");
         p.setPassword("yossarianspassword");
         p.setAuthorities(TEST_AUTHORITIES);
 
         mgr.createUser(p.createUserDetails());
 
         SecurityContextHolder.getContext().setAuthentication(
-                new UsernamePasswordAuthenticationToken("john", "yossarianspassword", TEST_AUTHORITIES));
+                new UsernamePasswordAuthenticationToken("johnyossarian", "yossarianspassword", TEST_AUTHORITIES));
 
         mgr.changePassword("yossarianspassword", "yossariansnewpassword");
 
-        
+        assertTrue(template.compare("uid=johnyossarian,ou=testpeople,dc=acegisecurity,dc=org",
+                "userPassword", "yossariansnewpassword"));
+    }
 
+    public void testPasswordChangeWithWrongOldPasswordFails() {
+        InetOrgPerson.Essence p = new InetOrgPerson.Essence();
+        p.setCn(new String[] {"John Yossarian"});
+        p.setSn("Yossarian");
+        p.setUid("johnyossarian");
+        p.setPassword("yossarianspassword");
+        p.setAuthorities(TEST_AUTHORITIES);
 
+        mgr.createUser(p.createUserDetails());
 
+        SecurityContextHolder.getContext().setAuthentication(
+                new UsernamePasswordAuthenticationToken("johnyossarian", "yossarianspassword", TEST_AUTHORITIES));
 
+        try {
+            mgr.changePassword("wrongpassword", "yossariansnewpassword");
+            fail("Expected BadCredentialsException");
+        } catch (BadCredentialsException expected) {
+        }
 
     }
 }

+ 2 - 3
core/src/test/java/org/acegisecurity/userdetails/ldap/LdapUserDetailsMapperTests.java

@@ -20,9 +20,8 @@ import junit.framework.TestCase;
 import javax.naming.directory.BasicAttributes;
 import javax.naming.directory.BasicAttribute;
 
-import org.acegisecurity.GrantedAuthorityImpl;
-import org.springframework.ldap.support.DirContextAdapter;
-import org.springframework.ldap.support.DistinguishedName;
+import org.springframework.ldap.core.DirContextAdapter;
+import org.springframework.ldap.core.DistinguishedName;
 
 /**
  * Tests {@link LdapUserDetailsMapper}.