turnred/ldap-bundle

Symfony 2 的 LDAP Bundle

v2.3.1 2014-02-26 13:30 UTC

README

LdapBundle 提供了不使用 Apache 的 mod_ldap 的 LDAP 身份验证。该包依赖于 PHP 的 LDAP 扩展 和一个用于用户身份验证的表单。LdapBundle 还可以用于授权,通过检索 LDAP 中定义的用户角色。

联系方式

昵称: aways IRC: irc.freenode.net - #symfony-fr

安装

  1. 使用 composer 下载
  2. 启用 Bundle
  3. 在 security.yml 中配置 LdapBundle
  4. 导入 LdapBundle 路由
  5. 实现注销
  6. 使用链式提供者
  7. 订阅 PRE_BIND 事件
  8. 订阅 POST_BIND 事件

获取 Bundle

Composer

在项目的 composer.json 中添加 LdapBundle

{
    "require": {
        "imag/ldap-bundle": "dev-master"
    }
}

启用 Bundle

<?php
// app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        // ...
        new IMAG\LdapBundle\IMAGLdapBundle(),
    );
}

配置 security.yml

注意

示例 security.yml 文件位于包内 ./Resources/Docs/security.yml

# ./IMAG/LdapBundle/Resources/config/security.yml

security:
  firewalls:
    restricted_area:
      pattern:          ^/
      anonymous:        ~
      provider:         ldap
      imag_ldap:        ~
      # alternative configuration
      # imag_ldap:
      #   login_path:   /ninja/login
      logout:
        path:           /logout
        target:         /

  providers:
    ldap:
      id: imag_ldap.security.user.provider
                
  encoders:
    IMAG\LdapBundle\User\LdapUser: plaintext

  access_control:
    - { path: ^/login,          roles: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/,               roles: IS_AUTHENTICATED_FULLY }

imag_ldap:
  client:
    host: your.host.foo
    port: 389
#    version: 3 # Optional
#    username: foo # Optional
#    password: bar # Optional
#    network_timeout: 10 # Optional
#    referrals_enabled: true # Optional
#    bind_username_before: true # Optional
#    skip_roles: false # Optional

  user:
    base_dn: ou=people,dc=host,dc=foo
#    filter: (&(foo=bar)(ObjectClass=Person)) #Optional
    name_attribute: uid
  role:
    base_dn: ou=group, dc=host, dc=foo
#    filter: (ou=group) #Optional
    name_attribute: cn
    user_attribute: member
    user_id: [ dn or username ]
    
#  user_class: IMAG\LdapBundle\User\LdapUser # Optional

您应该根据您的环境配置 imag_ldap 部分下的参数。

注意

如果未设置,则可选参数有默认值。您可以通过设置参数为 NULL 来禁用默认值。

# app/config/security.yml
imag_ldap:
  # ...
  role:
    # ...
    filter: NULL

导入路由

# app/config/routing.yml

imag_ldap:
  resource: "@IMAGLdapBundle/Resources/config/routing.yml"

实现注销

只需创建一个带有注销目标的链接。

<a href="{{ path('logout') }}">Logout</a>

注意

您可以参考官方的 Symfony 文档: https://symfony.com.cn/doc/current/book/security.html#logging-out

链式提供者

您还可以将登录表单与数据库提供者、内存提供者等其他提供者链式连接。

# app/config/security.yml
security:
    firewalls:
        secured_area:
            pattern: ^/
            anonymous: ~
            imag_ldap:
                provider: multiples
            logout:
                path: logout
    providers:
        multiples:
            chain:
                providers: [ldap, db]          
        ldap:
            id: imag_ldap.security.user.provider
        db:
            entity: { class: FQDN\User }

注意

如果您设置了配置选项 bind_username_before: true,则必须将提供者链中的 LDAP 提供者放在最后位置。

# app/config/security.yml

providers: [db, ldap]          

订阅 PRE_BIND 事件

PRE_BIND 在用户通过 LDAP 进行身份验证之前触发。在这里,您可以编写一个监听器在用户绑定/验证到 LDAP 之前执行自己的逻辑。例如,添加自己的角色或对应用程序进行其他身份验证/授权检查。

如果您想在监听器中中断身份验证过程,则抛出异常。

示例监听器

<service id="ldap.listener" class="Acme\HelloBundle\EventListener\LdapSecuritySubscriber">
    <tag name="kernel.event_subscriber" />
</service>

示例

<?php

namespace Acme\HelloBundle\EventListener;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use IMAG\LdapBundle\Event\LdapUserEvent;

/**
 * Performs logic before the user is found to LDAP
 */
class LdapSecuritySubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        return array(
            \IMAG\LdapBundle\Event\LdapEvents::PRE_BIND => 'onPreBind',
        );
    }

    /**
     * Modifies the User before binding data from LDAP
     *
     * @param \IMAG\LdapBundle\Event\LdapUserEvent $event
     */
    public function onPreBind(LdapUserEvent $event)
    {
        $user = $event->getUser();
        $config = $this->appContext->getConfig();

        $ldapConf = $config['ldap'];

        if (!in_array($user->getUsername(), $ldapConf['allowed'])) {
            throw new \Exception(sprintf('LDAP user %s not allowed', $user->getUsername()));
        }

		$user->addRole('ROLE_LDAP');
        $event->setUser($user);
    }
}

订阅 POST_BIND 事件

POST_BIND 在用户通过 LDAP 进行身份验证之后触发。您可以像 PRE_BIND 一样使用它。

注意

但是,每次页面刷新时,Symfony 都会调用提供者中的 refreshUser 方法,而不触发这些事件(PRE_BIND 和 POST_BIND)。如果您想要覆盖用户(例如像凭证、角色...),则必须创建一个新的提供者并重写此方法。