Symfony 4 中的 LDAP 角色

LDAP role in Symfony 4

我在 Symfony 4 的项目中使用 ldap 组件。它运行良好,验证成功,但我可以为用户设置的唯一角色是 ldap 提供程序选项中提供的 default_role在 security.yaml... 我发现的所有文档都不是很有帮助,无论人们是使用数据库来管理用户还是他们在使用 ldap 组件时不谈论角色。 如果需要,这是我的 security.yaml :

security.yaml :

security:
# https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
providers:
    #in_memory: { memory: null }

    my_ldap:
        ldap:
            service: Symfony\Component\Ldap\Ldap
            base_dn: 'my_base_dn'
            search_dn: 'my_search_dn'
            search_password: '%env(resolve:LDAP_PASSWORD)%'
            default_roles: ROLE_USER #rôle par défaut donné à l'utilisateur authentifié

firewalls:
    dev:
        pattern: ^/(_(profiler|wdt)|css|images|js)/
        security: false
    main:
        anonymous: ~

        form_login_ldap:
            provider: my_ldap
            service: Symfony\Component\Ldap\Ldap
            dn_string: 'my_dn_string'
            query_string: '(&(sAMAccountName={username})(memberOf=CN=***))'
            login_path: login #route vers laquelle l'utilisateur sera redirigé si il tente d'accéder à une ressource protégé sans être authentifié
        #/!\/!\/!\ NE PAS METTRE EN COMMENTAIRE SINON SUPPRESSION DES LOGS D'ERREURS !! /!\/!\/!\
            check_path: login #route vers laquelle doit être envoyé la requête POST du formulaire
            always_use_default_target_path: true
            default_target_path: homePage #page vers laquelle l'utilisateur authentifié est redirigé

        logout:
                path: app_logout
                target: login
        # activate different ways to authenticate
        # https://symfony.com/doc/current/security.html#firewalls-authentication

        # https://symfony.com/doc/current/security/impersonating_user.html
        # switch_user: true

如果有人有解决方案或想法!!

我正在寻找相同的功能,但似乎尚未实现。

然而,there is a feature request for this on GitHub.

如果 您的 LDAP 将组成员身份保存为用户的一个属性,一种解决方法是在控制器中检查用户对象的此属性并可能拒绝访问。您可以为此创建一个单独的方法,并确保在每个需要安全检查的操作方法中调用它,如下所示:

<?php
namespace App\Controller;

use Symfony\Component\Security\Core\Exception\AccessDeniedException;

class SampleController extends AbstractController
{
    public function index()
    {
        $ldapGroup = 'LDAP-User-Group';
        $this->denyAccessUnlessLdapGroup($ldapGroup, 'ROLE_USER');
        // continue if authenticated
    }

    /**
     * Throws an exception unless the current user is member of the specified ldap group
     *
     * @throws AccessDeniedException
     *
     */    
    private function denyAccessUnlessLdapGroup($ldapGroup, $attributes, string $message = 'Access Denied.') {
        $ldapAttribute = 'memberof';
        // usually you'll want to make sure the user is authenticated first
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');

        // returns your User object, or null if the user is not authenticated
        // use inline documentation to tell your editor your exact User class
        // in this case: \Symfony\Component\Ldap\Security\LdapUser
        /** @var \App\Entity\User $user */
        $user = $this->getUser();
        /** @var \Synfony\Component\Ldap\Entry $entry */
        $entry = $user->getEntry();
        if(!$entry->getAttribute($ldapAttribute) ||
         !in_array($ldapGroup, $entry->getAttribute($ldapAttribute))) {
            $exception = $this->createAccessDeniedException($message);
            $exception->setAttributes($attributes);

            throw $exception;    
        }
    }
}

确保自定义 $ldapGroupldapAttribute。传递给 $attributes 的值此时没有意义;为了与其他 denyAccess* 方法保持一致,我保留了它。