我试图在用户通过LDAP登录时根据其LDAP dn授予角色。 为此,我想从Symfony \ Component \ Security \ Core \ User \ LdapUserProvider中重写loadUser方法,但是如果我理解正确的话,我真的不知道如何进行(我在使用时是相当新的Symfony:p),它不是服务,而是其中一部分? 因此,有没有一种方法可以轻松地重写该方法,还是我需要重新定义整个Ldap服务?
我尝试过的是:
// app/config/services.yml
[...]
Symfony\Component\Ldap\Ldap:
arguments: ['@Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']
Symfony\Component\Security\Core\User\LdapUserProvider:
class: AppBundle\Services\LdapUserProvider
Symfony\Component\Ldap\Adapter\ExtLdap\Adapter:
arguments:
- host: '%ldap_host%'
port: '%ldap_port%'
// src/Services/LdapUserProvider.php
namespace AppBundle\Services;
use Symfony\Component\Ldap\Entry;
class LdapUserProvider extends \Symfony\Component\Security\Core\User\LdapUserProvider {
protected function loadUser($username, Entry $entry)
{
$password = null;
if (null !== $this->passwordAttribute) {
$password = $this->getAttributeValue($entry, $this->passwordAttribute);
}
return new User($username, $password, array('ROLE_TEST'));
}
}
但是,它当然不起作用,而且我没有ROLE_TEST角色。
预先感谢!
答案 0 :(得分:0)
您可以使用本教程:
https://medium.com/@devstan/extended-ldap-with-symfony-3-30be6f1a36b1
,您应该创建一个实现LdapUser
UserInterface
类
1.LDAP用户提供者
<?php
namespace YourAppBundle\Security\User;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Ldap\Entry;
use Symfony\Component\Security\Core\User\LdapUserProvider as BaseLdapUserProvider;
class LdapUserProvider extends BaseLdapUserProvider
{
/**
* {@inheritdoc}
*/
public function refreshUser(UserInterface $user)
{
if (!$user instanceof LdapUser) {
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', get_class($user)));
}
return new LdapUser($user->getUsername(), null, $user->getRoles(), $user->getLdapEntry());
}
/**
* {@inheritdoc}
*/
public function supportsClass($class)
{
return $class === 'YourAppBundle\Security\User\LdapUser';
}
/**
* {@inheritdoc}
*/
protected function loadUser($username, Entry $entry)
{
$user = parent::loadUser($username, $entry);
return new LdapUser($username, $user->getPassword(), $user->getRoles(), $entry);
}
}
2.LDAP用户
<?php
namespace YourAppBundle\Security\User;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Ldap\Entry;
class LdapUser implements UserInterface
{
const LDAP_KEY_DISPLAY_NAME = 'displayName';
const LDAP_KEY_MAIL = 'mail';
protected $username;
protected $password;
protected $roles;
protected $ldapEntry;
protected $displayName;
protected $eMail;
public function __construct($username, $password, array $roles, Entry $ldapEntry)
{
if ('' === $username || null === $username) {
throw new \InvalidArgumentException('The username cannot be empty.');
}
$this->username = $username;
$this->password = $password;
$this->roles = $roles;
$this->ldapEntry = $ldapEntry;
$this->displayName = $this->extractSingleValueByKeyFromEntry(
$ldapEntry,
self::LDAP_KEY_DISPLAY_NAME,
$username
);
$this->eMail = $this->extractSingleValueByKeyFromEntry($ldapEntry, self::LDAP_KEY_MAIL);
}
public function __toString()
{
return (string) $this->getUsername();
}
public function getDisplayName()
{
return $this->displayName;
}
/**
* @return Entry
*/
public function getLdapEntry()
{
return $this->ldapEntry;
}
/**
* {@inheritdoc}
*/
public function getRoles()
{
return $this->roles;
}
/**
* {@inheritdoc}
*/
public function getPassword()
{
return $this->password;
}
/**
* {@inheritdoc}
*/
public function getSalt()
{
}
/**
* {@inheritdoc}
*/
public function getUsername()
{
return $this->username;
}
/**
* {@inheritdoc}
*/
public function eraseCredentials()
{
}
/**
* Extracts single value from entry's array value by key.
*
* @param Entry $entry Ldap entry
* @param string $key Key
* @param null|string $defaultValue Default value
*
* @return string|null
*/
protected function extractSingleValueByKeyFromEntry(Entry $entry, $key, $defaultValue = null)
{
$value = $this->extractFromLdapEntry($entry, $key, $defaultValue);
return is_array($value) && isset($value[0]) ? $value[0] : $defaultValue;
}
/**
* Extracts value from entry by key.
*
* @param Entry $entry Ldap entry
* @param string $key Key
* @param mixed $defaultValue Default value
*
* @return array|mixed
*/
protected function extractFromLdapEntry(Entry $entry, $key, $defaultValue = null)
{
if (!$entry->hasAttribute($key)) {
return $defaultValue;
}
return $entry->getAttribute($key);
}
}
3.Services.yml
我们需要定义我们新创建的ldap用户提供者服务
services:
...
app.ldap:
class: Symfony\Component\Ldap\Ldap
factory: ['Symfony\Component\Ldap\Ldap', 'create']
arguments:
- 'ext_ldap'
- host: '%ldap_host%'
app.ext_ldap_user_provider:
class: YourAppBundle\Security\User\LdapUserProvider
arguments:
- '@app.ldap' # LDAP component instance
- '%ldap_base_dn%' # Base dn
- '%ldap_search_dn%' # Search dn
- '%ldap_search_password%' # Search user password
- ['ROLE_SUPER_ADMIN'] # Roles
- '%ldap_uid_key%' # LDAP uid key
- '%ldap_filter%' # filter
4.Security.yml
这只是我们提供程序的一个示例用法—“ / ui”将通过LDAP保护。
security:
encoders:
...
YourAppBundle\Security\User\LdapUser:
algorithm: bcrypt
cost: 12
providers:
...
ldap_users:
id: app.ext_ldap_user_provider
...
firewalls:
frontend:
anonymous: ~
provider: ldap_users
form_login_ldap:
service: app.ldap
dn_string: '%ldap_dn_string%'
login_path: front-login
check_path: front-login
default_target_path: /ui
logout:
path: front-logout
target: front-login
access_control:
...
- { path: ^/ui/logout, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/ui/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/ui, roles: IS_AUTHENTICATED_FULLY }