make LdapBindAuthenticationProvider capable of searching for the DN
This commit is contained in:
parent
b9b6ebd643
commit
a30191f30a
@ -27,7 +27,7 @@ class FormLoginLdapFactory extends FormLoginFactory
|
||||
protected function createAuthProvider(ContainerBuilder $container, $id, $config, $userProviderId)
|
||||
{
|
||||
$provider = 'security.authentication.provider.ldap_bind.'.$id;
|
||||
$container
|
||||
$definition = $container
|
||||
->setDefinition($provider, new ChildDefinition('security.authentication.provider.ldap_bind'))
|
||||
->replaceArgument(0, new Reference($userProviderId))
|
||||
->replaceArgument(1, new Reference('security.user_checker.'.$id))
|
||||
@ -36,6 +36,10 @@ class FormLoginLdapFactory extends FormLoginFactory
|
||||
->replaceArgument(4, $config['dn_string'])
|
||||
;
|
||||
|
||||
if (!empty($config['query_string'])) {
|
||||
$definition->addMethodCall('setQueryString', array($config['query_string']));
|
||||
}
|
||||
|
||||
return $provider;
|
||||
}
|
||||
|
||||
@ -47,6 +51,7 @@ class FormLoginLdapFactory extends FormLoginFactory
|
||||
->children()
|
||||
->scalarNode('service')->defaultValue('ldap')->end()
|
||||
->scalarNode('dn_string')->defaultValue('{username}')->end()
|
||||
->scalarNode('query_string')->end()
|
||||
->end()
|
||||
;
|
||||
}
|
||||
|
@ -33,6 +33,7 @@ class LdapBindAuthenticationProvider extends UserAuthenticationProvider
|
||||
private $userProvider;
|
||||
private $ldap;
|
||||
private $dnString;
|
||||
private $queryString;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -53,6 +54,16 @@ class LdapBindAuthenticationProvider extends UserAuthenticationProvider
|
||||
$this->dnString = $dnString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a query string to use in order to find a DN for the username.
|
||||
*
|
||||
* @param string $queryString
|
||||
*/
|
||||
public function setQueryString($queryString)
|
||||
{
|
||||
$this->queryString = $queryString;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@ -79,7 +90,20 @@ class LdapBindAuthenticationProvider extends UserAuthenticationProvider
|
||||
|
||||
try {
|
||||
$username = $this->ldap->escape($username, '', LdapInterface::ESCAPE_DN);
|
||||
$dn = str_replace('{username}', $username, $this->dnString);
|
||||
|
||||
if ($this->queryString) {
|
||||
$query = str_replace('{username}', $username, $this->queryString);
|
||||
|
||||
$query = $this->ldap->query($this->dnString, $query);
|
||||
$result = $query->execute();
|
||||
if (1 !== $result->count()) {
|
||||
throw new BadCredentialsException('The presented username is invalid.');
|
||||
}
|
||||
|
||||
$dn = $result[0]->getDn();
|
||||
} else {
|
||||
$dn = str_replace('{username}', $username, $this->dnString);
|
||||
}
|
||||
|
||||
$this->ldap->bind($dn, $password);
|
||||
} catch (ConnectionException $e) {
|
||||
|
@ -12,6 +12,9 @@
|
||||
namespace Symfony\Component\Security\Core\Tests\Authentication\Provider;
|
||||
|
||||
use Symfony\Component\Ldap\LdapInterface;
|
||||
use Symfony\Component\Ldap\Entry;
|
||||
use Symfony\Component\Ldap\Adapter\QueryInterface;
|
||||
use Symfony\Component\Ldap\Adapter\CollectionInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Provider\LdapBindAuthenticationProvider;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
|
||||
use Symfony\Component\Security\Core\User\User;
|
||||
@ -81,4 +84,73 @@ class LdapBindAuthenticationProviderTest extends \PHPUnit_Framework_TestCase
|
||||
|
||||
$reflection->invoke($provider, 'foo', new UsernamePasswordToken('foo', 'bar', 'key'));
|
||||
}
|
||||
|
||||
public function testQueryForDn()
|
||||
{
|
||||
$userProvider = $this->getMockBuilder(UserProviderInterface::class)->getMock();
|
||||
|
||||
$collection = new \ArrayIterator(array(new Entry('')));
|
||||
|
||||
$query = $this->getMockBuilder(QueryInterface::class)->getMock();
|
||||
$query
|
||||
->expects($this->once())
|
||||
->method('execute')
|
||||
->will($this->returnValue($collection))
|
||||
;
|
||||
|
||||
$ldap = $this->getMockBuilder(LdapInterface::class)->getMock();
|
||||
$ldap
|
||||
->expects($this->once())
|
||||
->method('escape')
|
||||
->with('foo', '')
|
||||
->will($this->returnValue('foo'))
|
||||
;
|
||||
$ldap
|
||||
->expects($this->once())
|
||||
->method('query')
|
||||
->with('{username}', 'foobar')
|
||||
->will($this->returnValue($query))
|
||||
;
|
||||
$userChecker = $this->getMockBuilder(UserCheckerInterface::class)->getMock();
|
||||
|
||||
$provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap);
|
||||
$provider->setQueryString('{username}bar');
|
||||
$reflection = new \ReflectionMethod($provider, 'checkAuthentication');
|
||||
$reflection->setAccessible(true);
|
||||
|
||||
$reflection->invoke($provider, new User('foo', null), new UsernamePasswordToken('foo', 'bar', 'key'));
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\Security\Core\Exception\BadCredentialsException
|
||||
* @expectedExceptionMessage The presented username is invalid.
|
||||
*/
|
||||
public function testEmptyQueryResultShouldThrowAnException()
|
||||
{
|
||||
$userProvider = $this->getMockBuilder(UserProviderInterface::class)->getMock();
|
||||
|
||||
$collection = $this->getMockBuilder(CollectionInterface::class)->getMock();
|
||||
|
||||
$query = $this->getMockBuilder(QueryInterface::class)->getMock();
|
||||
$query
|
||||
->expects($this->once())
|
||||
->method('execute')
|
||||
->will($this->returnValue($collection))
|
||||
;
|
||||
|
||||
$ldap = $this->getMockBuilder(LdapInterface::class)->getMock();
|
||||
$ldap
|
||||
->expects($this->once())
|
||||
->method('query')
|
||||
->will($this->returnValue($query))
|
||||
;
|
||||
$userChecker = $this->getMockBuilder(UserCheckerInterface::class)->getMock();
|
||||
|
||||
$provider = new LdapBindAuthenticationProvider($userProvider, $userChecker, 'key', $ldap);
|
||||
$provider->setQueryString('{username}bar');
|
||||
$reflection = new \ReflectionMethod($provider, 'checkAuthentication');
|
||||
$reflection->setAccessible(true);
|
||||
|
||||
$reflection->invoke($provider, new User('foo', null), new UsernamePasswordToken('foo', 'bar', 'key'));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user