针对LDAP服务器进行身份认证

3.4 版本
维护中的版本

Symfony提供了不同的方法来配合LDAP服务器使用。

Security组件提供:

  • ldap user provider,使用的是 LdapUserProvider 类。同所有其他user provider一样,它可以同任何authentication provider一起使用。

  • form_login_ldap authentication provider,用于针对一台使用了表单登录的LDAP服务器。同所有其他user provider一样,它可以同任何authentication provider一起使用。

  • http_basic_ldap authentication provider,用于针对一台使用了HTTP Basic的LDAP服务器。同所有其他user provider一样,它可以同任何authentication provider一起使用。

这意味着在以下场合是可以工作的:

  • 利用一台LDAP服务器来比对用户密码并取出用户信息。这可以使用LDAP user provider,以及LDAP form login或LDAP HTTP basic两个authentication provider中的一种来完成。

  • 利用一台LDAP服务器来比对用户密码,但从另一个资源处取得用户信息(比如,一个使用了FOSUserBundle的数据库)。

  • 从一台LDAP服务器取出用户信息,同时使用另一种用户验证策略(比如,基于token的预验证)。

LDAP配置参考 

完整的LDAP配置参考 (form_login_ldap, http_basic_ldap, ldap) 请见 SecurityBundle Configuration ("security")。其中一些更有意思的选项在此进行解释。

配置LDAP客户端 

所有架构都需要LDAP客户端被预先配置好。providers被配置为使用一个名为 ldap 的服务,但你也可以在security组件的配置信息中覆写此项设置。

使用下列配置,一个LDAP客户端可以被简单地配置:

1
2
3
4
5
6
7
8
9
10
# app/config/services.yml
services:
    ldap:
        class: Symfony\Component\Ldap\LdapClient
        arguments:
            - my-server   # host
            - 389         # port
            - 3           # version
            - false       # SSL
            - true        # TLS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- app/config/services.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<container xmlns="http://symfony.com/schema/dic/services"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
 
    <services>
        <service id="ldap" class="Symfony\Component\Ldap\LdapClient">
            <argument>my-server</argument>
            <argument>389</argument>
            <argument>3</argument>
            <argument>false</argument>
            <argument>true</argument>
        </service>
    </services>
</container>
1
2
3
4
5
6
7
8
9
10
11
12
13
// app/config/services.php
use Symfony\Component\Ldap\LdapClient;
use Symfony\Component\DependencyInjection\Definition;
 
$container
    ->setDefinition('ldap', new Definition(LdapClient::class, array(
        'my-server',
        389,
        3,
        false,
        true,
 
    ));

利用LDAP User Provider取出用户 

如果你想从一台LDAP服务器中取出用户信息,你就需要使用 ldap user provider了:

1
2
3
4
5
6
7
8
9
10
11
12
13
# app/config/security.yml
security:
    # ...

    providers:
        my_ldap:
            ldap:
                service: ldap
                base_dn: dc=example,dc=com
                search_dn: "cn=read-only-admin,dc=example,dc=com"
                search_password: password
                default_roles: ROLE_USER
                uid_key: uid
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- app/config/security.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:srv="http://symfony.com/schema/dic/services"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">
 
    <config>
        <provider name="my_ldap">
            <ldap
                    service="ldap"
                    base-dn="dc=example,dc=com"
                    search-dn="cn=read-only-admin,dc=example,dc=com"
                    search-password="password"
                    default-roles="ROLE_USER"
                    uid-key="uid"
            />
        </provider>
    </config>
</srv:container>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$container->loadFromExtension('security', array(
    'providers' => array(
        'ldap_users' => array(
            'ldap' => array(
                'service' => 'ldap',
                'base_dn' => 'dc=example,dc=com',
                'search_dn' => 'cn=read-only-admin,dc=example,dc=com',
                'search_password' => 'password',
                'default_roles' => 'ROLE_USER',
                'uid_key' => 'uid',
            ),
        ),
    ),
);

ldap user provider支持多种不同的配置选项:

service 

值类型: string 默认值: ldap

这是你所配置的LDAP客户端的名字。你可以随便选择名称,但必须是程序中的唯一,并且不允许以数字或空格开头。

base_dn 

值类型: string 默认值: null

这是目录的base DN。

search_dn 

值类型: string 默认值: null

这是你的只读用户的DN,用于对LDAP服务器进行认证,以便取出用户信息。

search_password 

值类型: string 默认值: null

这是你的只读用户的密码,用于对LDAP服务器进行认证,以便取出用户信息。

default_roles 

值类型: array 默认值: []

这是你希望分配给“从LDAP服务器取出的用户”之默认role。如果你不配置此键,用户不会有任何role,并不被当作“完全认证”(fully authenticated)的用户。

uid_key 

值类型: string 默认值: sAMAccountName

这是入口点(entry)的key,用作其uid。取决于你的LDAP服务器之具体落实(implementation)。常用值是:

  • sAMAccountName
  • userPrincipalName
  • uid

filter 

值类型: string 默认值: ({uid_key}={username})

这个键让你配置哪个LDAP查询将被使用。{uid_key} 字符串将被 uid_key 配置值所替换 (默认时, sAMAccountName) 和 {username} 字符串将被你“正在尝试加载的用户名”给替换。

例如,带有一个 uid 值的 uid_key,如果你尝试加载 fabpot 用户,最终的字符串将会是: (uid=fabpot)

当然,用户名会被转义,为的是防止 LDAP injection

filter 选项键的语法被 RFC4515 所定义。

针对LDAP服务器进行身份认证 

针对LDAP服务器进行身份认证,可以藉由使用form login或是HTTP Basic两个authentication providers来完成。

除了两个选项键之外,它们和“非LDAP”情况下的配置完全一样:

service 

值类型: string 默认值: ldap

这是你所配置的LDAP客户端的名字。你可以随便选择名称,但必须是程序中的唯一,并且不允许以数字或空格开头。

dn_string 

值类型: string 默认值: {username}

这个键定义了“用于从用户名中组成用户的DN的字符串”的格式。{username} 字符串将被正在认证的人的真实用户名所替换。

例如,如果你的用户拥有 uid=einstein,dc=example,dc=com 这样一个DN字符串,那么 dn_string 将会是 uid={username},dc=example,dc=com

下面给出了 form_login_ldaphttp_basic_ldap 的配置示例。

表单登陆之配置示例 

1
2
3
4
5
6
7
8
9
10
11
12
13
# app/config/security.yml
security:
    # ...

    firewalls:
        main:
            # ...
            form_login_ldap:
                login_path: login
                check_path: login_check
                # ...
                service: ldap
                dn_string: 'uid={username},dc=example,dc=com'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!-- app/config/security.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:srv="http://symfony.com/schema/dic/services"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">
 
    <config>
        <firewall name="main">
            <form-login-ldap
                    login-path="login"
                    check-path="login_check"
                    service="ldap"
                    dn-string="uid={username},dc=example,dc=com" />
        </firewall>
    </config>
</srv:container>
1
2
3
4
5
6
7
8
9
10
11
12
13
$container->loadFromExtension('security', array(
    'firewalls' => array(
        'main' => array(
            'form_login_ldap' => array(
                'login_path' => 'login',
                'check_path' => 'login_check',
                'service' => 'ldap',
                'dn_string' => 'uid={username},dc=example,dc=com',
                // ...
            ),
        ),
    )
);

HTTP Basic登录之配置示例 

1
2
3
4
5
6
7
8
9
10
11
# app/config/security.yml
security:
    # ...

    firewalls:
        main:
            # ...
            http_basic_ldap:
                # ...
                service: ldap
                dn_string: 'uid={username},dc=example,dc=com'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<!-- app/config/security.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:srv="http://symfony.com/schema/dic/services"
    xsi:schemaLocation="http://symfony.com/schema/dic/services
        http://symfony.com/schema/dic/services/services-1.0.xsd">
 
    <config>
        <firewall name="main" stateless="true">
            <http-basic-ldap service="ldap" dn-string="uid={username},dc=example,dc=com" />
        </firewall>
    </config>
</srv:container>
1
2
3
4
5
6
7
8
9
10
11
12
$container->loadFromExtension('security', array(
    'firewalls' => array(
        'main' => array(
            'http_basic_ldap' => array(
                'service' => 'ldap',
                'dn_string' => 'uid={username},dc=example,dc=com',
                // ...
            ),
            'stateless' => true,
        ),
    ),
);

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)