Description
In implementing LDAP authentication in 2.8, we have found that authentication is limited to only users whose DNs fit the configured dn_string pattern. Let us consider this configuration:
security:
providers:
in_memory:
memory: ~
app_users:
ldap:
service: app.ldap
base_dn: %ldap.base_dn%
search_dn: null
search_password: null
filter: (uid={username})
default_roles: ROLE_USER
firewalls:
secure:
provider: app_users
stateless: true
pattern: ^/secure
http_basic_ldap:
service: app.ldap
dn_string: "uid={username},ou=people,dc=example,dc=com"
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
anonymous: ~
In this case, a user with DN "uid=foo,ou=people,dc=example,dc=com" can authenticate but one with DN "uid=foo,ou=something,ou=people,dc=example,dc=com" cannot, even though both accounts are in the configured search base.
The immediate reason is that after discovering information from LDAP with a call to ->find() in the LdapUserProvider::loadUserByUsername() method, the DN is discarded when LdapUserProvider::loadUser() creates the User instance.
Because the DN is discarded, later LdapBindAuthenticationProvider::checkAuthentication() recombines the basic username with what is configured in dn_string:
$dn = str_replace('{username}', $username, $this->dnString);
It would seem if User were extended to store the DN (perhaps by creating LdapUser with a setDn() method), it would not be necessary to set dn_string, and users in various OU's could authenticate.