Skip to content

Instantly share code, notes, and snippets.

@paulchubatyy
Last active October 5, 2018 14:55
Show Gist options
  • Select an option

  • Save paulchubatyy/b43e82905d6b84bf593f77f73cb0dfd4 to your computer and use it in GitHub Desktop.

Select an option

Save paulchubatyy/b43e82905d6b84bf593f77f73cb0dfd4 to your computer and use it in GitHub Desktop.
Snippets to map ldap groups to security roles in Symfony framework
<?php
namespace AppBundle;
use AppBundle\DependencyInjection\Compiler\LdapCompilerPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AppBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new LdapCompilerPass());
}
}
<?php
namespace AppBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class LdapCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$definition = $container->getDefinition('security.user.provider.ldap');
$definition->setClass('AppBundle\Security\LdapUserProvider');
}
}
<?php
namespace AppBundle\Security;
use Symfony\Component\Ldap\Entry;
use Symfony\Component\Security\Core\User\LdapUserProvider as SymfonyLdapUserProvider;
use Symfony\Component\Security\Core\User\User;
/**
* Handles the mapping of ldap groups to security roles.
* Class LdapUserProvider
* @package AppBundle\Security
*/
class LdapUserProvider extends SymfonyLdapUserProvider
{
/** @var array maps ldap groups to roles */
private $groupMapping = [ // Definitely requires modification for your setup
'managers' => 'ROLE_ADMIN',
'devops' => 'ROLE_SUPER_ADMIN'
];
/** @var string extracts group name from dn string */
private $groupNameRegExp = '/^CN=(?P<group>[^,]+),ou.*$/i'; // You might want to change it to match your ldap server
protected function loadUser($username, Entry $entry)
{
$roles = ['ROLE_USER']; // Actually we should be using $this->defaultRoles, but it's private. Has to be redesigned.
if (!$entry->hasAttribute('memberOf')) { // Check if the entry has attribute with the group
return new User($username, '', $roles);
}
foreach ($entry->getAttribute('memberOf') as $groupLine) { // Iterate through each group entry line
$groupName = strtolower($this->getGroupName($groupLine)); // Extract and normalize the group name fron the line
if (array_key_exists($groupName, $this->groupMapping)) { // Check if the group is in the mapping
$roles[] = $this->groupMapping[$groupName]; // Map the group to the role the user will have
}
}
return new User($username, '', $roles); // Create and return the user object
}
/**
* Get the group name from the DN
* @param string $dn
* @return string
*/
private function getGroupName($dn)
{
$matches = [];
return preg_match($this->groupNameRegExp, $dn, $matches) ? $matches['group'] : '';
}
}
@netfeld
Copy link
Copy Markdown

netfeld commented Oct 5, 2018

If you need to add custom services to youre LdapUserProvider you can do so by adding arguments in the process function:

    $argument = new Reference("your service ID");

    $definition = $container->getDefinition('security.user.provider.ldap');
    $definition->setClass('AppBundle\Security\LdapUserProvider');
    $definition->addArgument($argument );

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment