跳到内容

使用 LDAP 服务器进行身份验证

编辑此页

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

安全组件提供了:

  • ldap 用户提供器,使用 LdapUserProvider 类。像所有其他用户提供器一样,它可以与任何身份验证提供器一起使用。
  • form_login_ldap 身份验证提供器,用于使用登录表单针对 LDAP 服务器进行身份验证。像所有其他身份验证提供器一样,它可以与任何用户提供器一起使用。
  • http_basic_ldap 身份验证提供器,用于使用 HTTP Basic 针对 LDAP 服务器进行身份验证。像所有其他身份验证提供器一样,它可以与任何用户提供器一起使用。

这意味着以下场景将起作用:

  • 针对 LDAP 服务器检查用户的密码并获取用户信息。这可以使用 LDAP 用户提供器以及 LDAP 表单登录或 LDAP HTTP Basic 身份验证提供器来完成。
  • 针对 LDAP 服务器检查用户的密码,同时从另一个来源(例如您的主数据库)获取用户信息。
  • 从 LDAP 服务器加载用户信息,同时使用另一种身份验证策略(例如,基于令牌的预身份验证)。

安装

在使用 Symfony Flex 的应用程序中,运行此命令以在使用 Ldap 组件之前安装它:

1
$ composer require symfony/ldap

Ldap 配置参考

有关完整的 LDAP 配置参考 (form_login_ldaphttp_basic_ldapldap),请参阅 安全配置参考 (SecurityBundle)。下面解释了一些更有趣的选项。

配置 LDAP 客户端

所有机制实际上都需要预先配置的 LDAP 客户端。提供器配置为使用名为 ldap 的默认服务,但您可以在安全组件的配置中覆盖此设置。

可以使用内置的 LDAP PHP 扩展 以及以下服务定义来配置 LDAP 客户端:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# config/services.yaml
services:
    Symfony\Component\Ldap\Ldap:
        arguments: ['@Symfony\Component\Ldap\Adapter\ExtLdap\Adapter']
        tags:
            - ldap
    Symfony\Component\Ldap\Adapter\ExtLdap\Adapter:
        arguments:
            -   host: my-server
                port: 389
                encryption: tls
                options:
                    protocol_version: 3
                    referrals: false

使用 LDAP 用户提供器获取用户

如果您想从 LDAP 服务器获取用户信息,您可能需要使用 ldap 用户提供器。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# config/packages/security.yaml
security:
    # ...

    providers:
        my_ldap:
            ldap:
                service: Symfony\Component\Ldap\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
                extra_fields: ['email']

危险

当使用 LDAP 用户提供器时,安全组件会转义提供的输入数据。但是,LDAP 组件本身尚不提供任何转义。因此,当直接使用该组件时,您有责任防止 LDAP 注入攻击。

警告

上面在用户提供器中配置的用户仅用于检索数据。它是由其用户名和密码定义的静态用户(为了提高安全性,将密码定义为环境变量)。

如果您的 LDAP 服务器允许匿名检索信息,您可以将 search_dnsearch_password 选项设置为 null

ldap 用户提供器支持许多不同的配置选项:

service

类型: string 默认值: ldap

这是您配置的 LDAP 客户端的名称。您可以自由选择名称,但它在您的应用程序中必须是唯一的,并且不能以数字开头或包含空格。

base_dn

类型: string 默认值: null

这是目录的基本 DN。

search_dn

类型: string 默认值: null

这是您的只读用户的 DN,它将用于针对 LDAP 服务器进行身份验证以获取用户信息。

search_password

类型: string 默认值: null

这是您的只读用户的密码,它将用于针对 LDAP 服务器进行身份验证以获取用户信息。

default_roles

类型: array 默认值: []

这是您希望从 LDAP 服务器获取的用户获得的默认角色。如果您不配置此键,您的用户将没有任何角色,并且不会被视为完全通过身份验证。

uid_key

类型: string 默认值: null

这是要用作其 UID 的条目键。取决于您的 LDAP 服务器实现。常用值包括:

  • sAMAccountName (默认)
  • userPrincipalName
  • uid

如果您传递 null 作为此选项的值,则使用默认的 UID 键 sAMAccountName

extra_fields

类型: array 默认值: null

定义要从 LDAP 服务器拉取的自定义字段。如果任何字段不存在,将抛出 \InvalidArgumentException

filter

类型: string 默认值: null

此键允许您配置将使用的 LDAP 查询。{uid_key} 字符串将被 uid_key 配置值的值替换(默认情况下为 sAMAccountName),{user_identifier} 字符串将被您尝试加载的用户标识符替换。

例如,如果 uid_keyuid,并且您尝试加载用户 fabpot,则最终字符串将是:(uid=fabpot)

如果您传递 null 作为此选项的值,则使用默认过滤器 ({uid_key}={user_identifier})

为了防止 LDAP 注入,用户名将被转义。

filter 键的语法由 RFC4515 定义。

使用 LDAP 服务器进行身份验证

可以使用表单登录或 HTTP Basic 身份验证提供器对 LDAP 服务器进行身份验证。

它们的配置方式与非 LDAP 对应项完全相同,但增加了两个配置键和一个可选键:

service

类型: string 默认值: ldap

这是您配置的 LDAP 客户端的名称。您可以自由选择名称,但它在您的应用程序中必须是唯一的,并且不能以数字开头或包含空格。

dn_string

类型: string 默认值: {user_identifier}

此键定义了用于从用户名组成用户的 DN 字符串的形式。{user_identifier} 字符串将被尝试进行身份验证的人员的实际用户名替换。

例如,如果您的用户的 DN 字符串格式为 uid=einstein,dc=example,dc=com,则 dn_string 将是 uid={user_identifier},dc=example,dc=com

query_string

类型: string 默认值: null

此(可选)键使用户提供器搜索用户,然后使用找到的 DN 进行绑定过程。当将多个 LDAP 用户提供器与不同的 base_dn 一起使用时,这非常有用。此选项的值必须是有效的搜索字符串(例如 uid="{user_identifier}")。占位符值将被实际的用户标识符替换。

当使用此选项时,query_string 将在 dn_string 指定的 DN 中搜索,并且 query_string 的结果 DN 将用于使用其密码对用户进行身份验证。按照前面的示例,如果您的用户具有以下两个 DN:dc=companyA,dc=example,dc=comdc=companyB,dc=example,dc=com,则 dn_string 应为 dc=example,dc=com

请记住,用户名在两个 DN 中都必须是唯一的,因为如果找到多个用户,则身份验证提供程序将无法为绑定过程选择正确的用户。

下面提供了 form_login_ldaphttp_basic_ldap 的示例。

表单登录的配置示例

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

    firewalls:
        main:
            # ...
            form_login_ldap:
                # ...
                service: Symfony\Component\Ldap\Ldap
                dn_string: 'uid={user_identifier},dc=example,dc=com'

HTTP Basic 的配置示例

1
2
3
4
5
6
7
8
9
10
# config/packages/security.yaml
security:
    # ...

    firewalls:
        main:
            stateless: true
            http_basic_ldap:
                service: Symfony\Component\Ldap\Ldap
                dn_string: 'uid={user_identifier},dc=example,dc=com'

表单登录和 query_string 的配置示例

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

    firewalls:
        main:
            # ...
            form_login_ldap:
                service: Symfony\Component\Ldap\Ldap
                dn_string: 'dc=example,dc=com'
                query_string: '(&(uid={user_identifier})(memberOf=cn=users,ou=Services,dc=example,dc=com))'
                search_dn: '...'
                search_password: 'the-raw-password'
本作品,包括代码示例,根据 Creative Commons BY-SA 3.0 许可获得许可。
目录
    版本