使用 LDAP 服务器进行身份验证
Symfony 提供了不同的方法来使用 LDAP 服务器。
安全组件提供了:
ldap用户提供器,使用 LdapUserProvider 类。像所有其他用户提供器一样,它可以与任何身份验证提供器一起使用。form_login_ldap身份验证提供器,用于使用登录表单针对 LDAP 服务器进行身份验证。像所有其他身份验证提供器一样,它可以与任何用户提供器一起使用。http_basic_ldap身份验证提供器,用于使用 HTTP Basic 针对 LDAP 服务器进行身份验证。像所有其他身份验证提供器一样,它可以与任何用户提供器一起使用。
这意味着以下场景将起作用:
- 针对 LDAP 服务器检查用户的密码并获取用户信息。这可以使用 LDAP 用户提供器以及 LDAP 表单登录或 LDAP HTTP Basic 身份验证提供器来完成。
- 针对 LDAP 服务器检查用户的密码,同时从另一个来源(例如您的主数据库)获取用户信息。
- 从 LDAP 服务器加载用户信息,同时使用另一种身份验证策略(例如,基于令牌的预身份验证)。
Ldap 配置参考
有关完整的 LDAP 配置参考 (form_login_ldap、http_basic_ldap、ldap),请参阅 安全配置参考 (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_dn 和 search_password 选项设置为 null。
ldap 用户提供器支持许多不同的配置选项:
uid_key
类型: string 默认值: null
这是要用作其 UID 的条目键。取决于您的 LDAP 服务器实现。常用值包括:
sAMAccountName(默认)userPrincipalNameuid
如果您传递 null 作为此选项的值,则使用默认的 UID 键 sAMAccountName。
filter
类型: string 默认值: null
此键允许您配置将使用的 LDAP 查询。{uid_key} 字符串将被 uid_key 配置值的值替换(默认情况下为 sAMAccountName),{user_identifier} 字符串将被您尝试加载的用户标识符替换。
例如,如果 uid_key 为 uid,并且您尝试加载用户 fabpot,则最终字符串将是:(uid=fabpot)。
如果您传递 null 作为此选项的值,则使用默认过滤器 ({uid_key}={user_identifier})。
为了防止 LDAP 注入,用户名将被转义。
filter 键的语法由 RFC4515 定义。
使用 LDAP 服务器进行身份验证
可以使用表单登录或 HTTP Basic 身份验证提供器对 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=com 和 dc=companyB,dc=example,dc=com,则 dn_string 应为 dc=example,dc=com。
请记住,用户名在两个 DN 中都必须是唯一的,因为如果找到多个用户,则身份验证提供程序将无法为绑定过程选择正确的用户。
下面提供了 form_login_ldap 和 http_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'