使用 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
(默认)userPrincipalName
uid
如果您传递 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'