diff --git a/ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java b/ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java index d04e13d7b49..18bc258f882 100644 --- a/ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java +++ b/ldap/src/main/java/org/springframework/security/ldap/authentication/ad/ActiveDirectoryLdapAuthenticationProvider.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2016 the original author or authors. + * Copyright 2002-2024 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,12 +17,9 @@ package org.springframework.security.ldap.authentication.ad; import java.io.Serializable; -import java.util.ArrayList; -import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Hashtable; -import java.util.List; import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -39,7 +36,6 @@ import org.springframework.dao.IncorrectResultSizeDataAccessException; import org.springframework.ldap.CommunicationException; import org.springframework.ldap.core.DirContextOperations; -import org.springframework.ldap.core.DistinguishedName; import org.springframework.ldap.core.support.DefaultDirObjectFactory; import org.springframework.ldap.support.LdapUtils; import org.springframework.security.authentication.AccountExpiredException; @@ -50,11 +46,10 @@ import org.springframework.security.authentication.LockedException; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.AuthorityUtils; -import org.springframework.security.core.authority.SimpleGrantedAuthority; import org.springframework.security.core.userdetails.UsernameNotFoundException; import org.springframework.security.ldap.SpringSecurityLdapTemplate; import org.springframework.security.ldap.authentication.AbstractLdapAuthenticationProvider; +import org.springframework.security.ldap.userdetails.LdapAuthoritiesPopulator; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -72,9 +67,9 @@ *
* The user authorities are obtained from the data contained in the {@code memberOf} * attribute. - * + *
*
* When an authentication fails, resulting in a standard LDAP 49 error code, Active * Directory also supplies its own sub-error codes within the error message. These will be * used to provide additional log information on why an authentication has failed. Typical @@ -90,13 +85,14 @@ *
* If you set the {@link #setConvertSubErrorCodesToExceptions(boolean)
* convertSubErrorCodesToExceptions} property to {@code true}, the codes will also be used
* to control the exception raised.
*
* @author Luke Taylor
* @author Rob Winch
+ * @author Roman Zabaluev
* @since 3.1
*/
public final class ActiveDirectoryLdapAuthenticationProvider extends AbstractLdapAuthenticationProvider {
@@ -135,20 +131,23 @@ public final class ActiveDirectoryLdapAuthenticationProvider extends AbstractLda
// Only used to allow tests to substitute a mock LdapContext
ContextFactory contextFactory = new ContextFactory();
+ private LdapAuthoritiesPopulator authoritiesPopulator = new DefaultActiveDirectoryAuthoritiesPopulator();
+
/**
- * @param domain the domain name (may be null or empty)
+ * @param domain the domain name (can be null or empty)
* @param url an LDAP url (or multiple URLs)
- * @param rootDn the root DN (may be null or empty)
+ * @param rootDn the root DN (can be null or empty)
*/
public ActiveDirectoryLdapAuthenticationProvider(String domain, String url, String rootDn) {
Assert.isTrue(StringUtils.hasText(url), "Url cannot be empty");
this.domain = StringUtils.hasText(domain) ? domain.toLowerCase() : null;
this.url = url;
this.rootDn = StringUtils.hasText(rootDn) ? rootDn.toLowerCase() : null;
+ this.setAuthoritiesPopulator(this.authoritiesPopulator);
}
/**
- * @param domain the domain name (may be null or empty)
+ * @param domain the domain name (can be null or empty)
* @param url an LDAP url (or multiple URLs)
*/
public ActiveDirectoryLdapAuthenticationProvider(String domain, String url) {
@@ -156,6 +155,7 @@ public ActiveDirectoryLdapAuthenticationProvider(String domain, String url) {
this.domain = StringUtils.hasText(domain) ? domain.toLowerCase() : null;
this.url = url;
this.rootDn = (this.domain != null) ? rootDnFromDomain(this.domain) : null;
+ this.setAuthoritiesPopulator(this.authoritiesPopulator);
}
@Override
@@ -179,26 +179,10 @@ protected DirContextOperations doAuthentication(UsernamePasswordAuthenticationTo
}
}
- /**
- * Creates the user authority list from the values of the {@code memberOf} attribute
- * obtained from the user's Active Directory entry.
- */
@Override
protected Collection extends GrantedAuthority> loadUserAuthorities(DirContextOperations userData, String username,
String password) {
- String[] groups = userData.getStringAttributes("memberOf");
- if (groups == null) {
- this.logger.debug("No values for 'memberOf' attribute.");
- return AuthorityUtils.NO_AUTHORITIES;
- }
- if (this.logger.isDebugEnabled()) {
- this.logger.debug("'memberOf' attribute values: " + Arrays.asList(groups));
- }
- List