|
@@ -36,6 +36,7 @@ import javax.naming.directory.SearchControls;
|
|
|
import javax.naming.ldap.ExtendedRequest;
|
|
|
import javax.naming.ldap.ExtendedResponse;
|
|
|
import javax.naming.ldap.LdapContext;
|
|
|
+import javax.naming.ldap.LdapName;
|
|
|
|
|
|
import org.apache.commons.logging.Log;
|
|
|
import org.apache.commons.logging.LogFactory;
|
|
@@ -49,6 +50,7 @@ import org.springframework.ldap.core.DirContextAdapter;
|
|
|
import org.springframework.ldap.core.DistinguishedName;
|
|
|
import org.springframework.ldap.core.LdapTemplate;
|
|
|
import org.springframework.ldap.core.SearchExecutor;
|
|
|
+import org.springframework.ldap.support.LdapNameBuilder;
|
|
|
import org.springframework.security.authentication.BadCredentialsException;
|
|
|
import org.springframework.security.core.Authentication;
|
|
|
import org.springframework.security.core.GrantedAuthority;
|
|
@@ -93,7 +95,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
|
|
|
LdapUsernameToDnMapper usernameMapper = new DefaultLdapUsernameToDnMapper("cn=users", "uid");
|
|
|
|
|
|
/** The DN under which groups are stored */
|
|
|
- private DistinguishedName groupSearchBase = new DistinguishedName("cn=groups");
|
|
|
+ private LdapName groupSearchBase = LdapNameBuilder.newInstance("cn=groups").build();
|
|
|
|
|
|
/** Password attribute name */
|
|
|
private String passwordAttributeName = "userPassword";
|
|
@@ -137,14 +139,14 @@ public class LdapUserDetailsManager implements UserDetailsManager {
|
|
|
|
|
|
@Override
|
|
|
public UserDetails loadUserByUsername(String username) {
|
|
|
- DistinguishedName dn = this.usernameMapper.buildDn(username);
|
|
|
+ LdapName dn = this.usernameMapper.buildLdapName(username);
|
|
|
List<GrantedAuthority> authorities = getUserAuthorities(dn, username);
|
|
|
this.logger.debug(LogMessage.format("Loading user '%s' with DN '%s'", username, dn));
|
|
|
DirContextAdapter userCtx = loadUserAsContext(dn, username);
|
|
|
return this.userDetailsMapper.mapUserFromContext(userCtx, username, authorities);
|
|
|
}
|
|
|
|
|
|
- private DirContextAdapter loadUserAsContext(final DistinguishedName dn, final String username) {
|
|
|
+ private DirContextAdapter loadUserAsContext(final LdapName dn, final String username) {
|
|
|
return (DirContextAdapter) this.template.executeReadOnly((ContextExecutor) (ctx) -> {
|
|
|
try {
|
|
|
Attributes attrs = ctx.getAttributes(dn, this.attributesToRetrieve);
|
|
@@ -188,7 +190,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
|
|
|
"No authentication object found in security context. Can't change current user's password!");
|
|
|
String username = authentication.getName();
|
|
|
this.logger.debug(LogMessage.format("Changing password for user '%s'", username));
|
|
|
- DistinguishedName userDn = this.usernameMapper.buildDn(username);
|
|
|
+ LdapName userDn = this.usernameMapper.buildLdapName(username);
|
|
|
if (this.usePasswordModifyExtensionOperation) {
|
|
|
changePasswordUsingExtensionOperation(userDn, oldPassword, newPassword);
|
|
|
}
|
|
@@ -204,13 +206,13 @@ public class LdapUserDetailsManager implements UserDetailsManager {
|
|
|
* @return the granted authorities returned by the group search
|
|
|
*/
|
|
|
@SuppressWarnings("unchecked")
|
|
|
- List<GrantedAuthority> getUserAuthorities(final DistinguishedName dn, final String username) {
|
|
|
+ List<GrantedAuthority> getUserAuthorities(final LdapName dn, final String username) {
|
|
|
SearchExecutor se = (ctx) -> {
|
|
|
- DistinguishedName fullDn = LdapUtils.getFullDn(dn, ctx);
|
|
|
+ LdapName fullDn = LdapUtils.getFullDn(dn, ctx);
|
|
|
SearchControls ctrls = new SearchControls();
|
|
|
ctrls.setReturningAttributes(new String[] { this.groupRoleAttributeName });
|
|
|
- return ctx.search(this.groupSearchBase, this.groupSearchFilter, new String[] { fullDn.toUrl(), username },
|
|
|
- ctrls);
|
|
|
+ return ctx.search(this.groupSearchBase, this.groupSearchFilter,
|
|
|
+ new String[] { fullDn.toString(), username }, ctrls);
|
|
|
};
|
|
|
AttributesMapperCallbackHandler roleCollector = new AttributesMapperCallbackHandler(this.roleMapper);
|
|
|
this.template.search(se, roleCollector);
|
|
@@ -221,7 +223,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
|
|
|
public void createUser(UserDetails user) {
|
|
|
DirContextAdapter ctx = new DirContextAdapter();
|
|
|
copyToContext(user, ctx);
|
|
|
- DistinguishedName dn = this.usernameMapper.buildDn(user.getUsername());
|
|
|
+ LdapName dn = this.usernameMapper.buildLdapName(user.getUsername());
|
|
|
this.logger.debug(LogMessage.format("Creating new user '%s' with DN '%s'", user.getUsername(), dn));
|
|
|
this.template.bind(dn, ctx, null);
|
|
|
// Check for any existing authorities which might be set for this
|
|
@@ -235,7 +237,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
|
|
|
|
|
|
@Override
|
|
|
public void updateUser(UserDetails user) {
|
|
|
- DistinguishedName dn = this.usernameMapper.buildDn(user.getUsername());
|
|
|
+ LdapName dn = this.usernameMapper.buildLdapName(user.getUsername());
|
|
|
this.logger.debug(LogMessage.format("Updating new user '%s' with DN '%s'", user.getUsername(), dn));
|
|
|
List<GrantedAuthority> authorities = getUserAuthorities(dn, user.getUsername());
|
|
|
DirContextAdapter ctx = loadUserAsContext(dn, user.getUsername());
|
|
@@ -260,14 +262,14 @@ public class LdapUserDetailsManager implements UserDetailsManager {
|
|
|
|
|
|
@Override
|
|
|
public void deleteUser(String username) {
|
|
|
- DistinguishedName dn = this.usernameMapper.buildDn(username);
|
|
|
+ LdapName dn = this.usernameMapper.buildLdapName(username);
|
|
|
removeAuthorities(dn, getUserAuthorities(dn, username));
|
|
|
this.template.unbind(dn);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public boolean userExists(String username) {
|
|
|
- DistinguishedName dn = this.usernameMapper.buildDn(username);
|
|
|
+ LdapName dn = this.usernameMapper.buildLdapName(username);
|
|
|
try {
|
|
|
Object obj = this.template.lookup(dn);
|
|
|
if (obj instanceof Context) {
|
|
@@ -285,33 +287,48 @@ public class LdapUserDetailsManager implements UserDetailsManager {
|
|
|
* @param group the name of the group
|
|
|
* @return the DN of the corresponding group, including the groupSearchBase
|
|
|
*/
|
|
|
+ @Deprecated
|
|
|
protected DistinguishedName buildGroupDn(String group) {
|
|
|
DistinguishedName dn = new DistinguishedName(this.groupSearchBase);
|
|
|
dn.add(this.groupRoleAttributeName, group.toLowerCase());
|
|
|
return dn;
|
|
|
}
|
|
|
|
|
|
+ protected LdapName buildGroupName(String group) {
|
|
|
+ return LdapNameBuilder.newInstance(buildGroupDn(group)).build();
|
|
|
+ }
|
|
|
+
|
|
|
protected void copyToContext(UserDetails user, DirContextAdapter ctx) {
|
|
|
this.userDetailsMapper.mapUserToContext(user, ctx);
|
|
|
}
|
|
|
|
|
|
+ @Deprecated
|
|
|
protected void addAuthorities(DistinguishedName userDn, Collection<? extends GrantedAuthority> authorities) {
|
|
|
- modifyAuthorities(userDn, authorities, DirContext.ADD_ATTRIBUTE);
|
|
|
+ modifyAuthorities(LdapNameBuilder.newInstance(userDn).build(), authorities, DirContext.ADD_ATTRIBUTE);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void addAuthorities(LdapName userDn, Collection<? extends GrantedAuthority> authorities) {
|
|
|
+ addAuthorities(new DistinguishedName(userDn), authorities);
|
|
|
}
|
|
|
|
|
|
+ @Deprecated
|
|
|
protected void removeAuthorities(DistinguishedName userDn, Collection<? extends GrantedAuthority> authorities) {
|
|
|
- modifyAuthorities(userDn, authorities, DirContext.REMOVE_ATTRIBUTE);
|
|
|
+ modifyAuthorities(LdapNameBuilder.newInstance(userDn).build(), authorities, DirContext.REMOVE_ATTRIBUTE);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected void removeAuthorities(LdapName userDn, Collection<? extends GrantedAuthority> authorities) {
|
|
|
+ removeAuthorities(new DistinguishedName(userDn), authorities);
|
|
|
}
|
|
|
|
|
|
- private void modifyAuthorities(final DistinguishedName userDn,
|
|
|
- final Collection<? extends GrantedAuthority> authorities, final int modType) {
|
|
|
+ private void modifyAuthorities(final LdapName userDn, final Collection<? extends GrantedAuthority> authorities,
|
|
|
+ final int modType) {
|
|
|
this.template.executeReadWrite((ContextExecutor) (ctx) -> {
|
|
|
for (GrantedAuthority authority : authorities) {
|
|
|
String group = convertAuthorityToGroup(authority);
|
|
|
- DistinguishedName fullDn = LdapUtils.getFullDn(userDn, ctx);
|
|
|
+ LdapName fullDn = LdapUtils.getFullDn(userDn, ctx);
|
|
|
ModificationItem addGroup = new ModificationItem(modType,
|
|
|
- new BasicAttribute(this.groupMemberAttributeName, fullDn.toUrl()));
|
|
|
- ctx.modifyAttributes(buildGroupDn(group), new ModificationItem[] { addGroup });
|
|
|
+ new BasicAttribute(this.groupMemberAttributeName, fullDn.toString()));
|
|
|
+ ctx.modifyAttributes(buildGroupName(group), new ModificationItem[] { addGroup });
|
|
|
}
|
|
|
return null;
|
|
|
});
|
|
@@ -334,7 +351,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
|
|
|
}
|
|
|
|
|
|
public void setGroupSearchBase(String groupSearchBase) {
|
|
|
- this.groupSearchBase = new DistinguishedName(groupSearchBase);
|
|
|
+ this.groupSearchBase = LdapNameBuilder.newInstance(groupSearchBase).build();
|
|
|
}
|
|
|
|
|
|
public void setGroupRoleAttributeName(String groupRoleAttributeName) {
|
|
@@ -413,8 +430,7 @@ public class LdapUserDetailsManager implements UserDetailsManager {
|
|
|
this.rolePrefix = rolePrefix;
|
|
|
}
|
|
|
|
|
|
- private void changePasswordUsingAttributeModification(DistinguishedName userDn, String oldPassword,
|
|
|
- String newPassword) {
|
|
|
+ private void changePasswordUsingAttributeModification(LdapName userDn, String oldPassword, String newPassword) {
|
|
|
ModificationItem[] passwordChange = new ModificationItem[] { new ModificationItem(DirContext.REPLACE_ATTRIBUTE,
|
|
|
new BasicAttribute(this.passwordAttributeName, newPassword)) };
|
|
|
if (oldPassword == null) {
|
|
@@ -438,11 +454,10 @@ public class LdapUserDetailsManager implements UserDetailsManager {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
- private void changePasswordUsingExtensionOperation(DistinguishedName userDn, String oldPassword,
|
|
|
- String newPassword) {
|
|
|
+ private void changePasswordUsingExtensionOperation(LdapName userDn, String oldPassword, String newPassword) {
|
|
|
this.template.executeReadWrite((dirCtx) -> {
|
|
|
LdapContext ctx = (LdapContext) dirCtx;
|
|
|
- String userIdentity = LdapUtils.getFullDn(userDn, ctx).encode();
|
|
|
+ String userIdentity = LdapUtils.getFullDn(userDn, ctx).toString();
|
|
|
PasswordModifyRequest request = new PasswordModifyRequest(userIdentity, oldPassword, newPassword);
|
|
|
try {
|
|
|
return ctx.extendedOperation(request);
|