jmleroy / ldap-bundle
Symfony 3的LDAP Bundle(向后兼容)
Requires
- php: >=5.3.3
- ext-ldap: *
- symfony/symfony: >2.6
README
LdapBundle提供了一种不使用Apache的mod_ldap
进行LDAP身份验证的方法。该Bundle依赖于PHP的LDAP扩展以及用于身份验证的用户表单。LdapBundle还可以通过检索在LDAP中定义的用户角色来进行授权。
致谢
此Bundle最初由Boris Morel创建,然后由Subramanya Vajiraya分叉。由于原始维护者已停止维护此Bundle,并且可能最后的分叉者也放弃了它(最后更新于2017年),并且我需要修复它,因此我既提交了拉取请求,也自己分叉了它。任何人都可以自由使用此Bundle并按需修改它。我将努力保持此Bundle的最新状态。如果您成功地更新了项目,请提交拉取请求,我将很高兴审查并合并它。
安装
- 使用composer下载
- 启用Bundle
- 在security.yml中配置LdapBundle
- 导入LdapBundle路由
- 实现注销
- 使用链式提供者
- 订阅PRE_BIND事件
- 订阅POST_BIND事件
获取Bundle
Composer
在您的项目的composer.json
中添加LdapBundle
{ "require": { "jmleroy/ldap-bundle": "dev-master" } }
或
composer require jmleroy/ldap-bundle
启用Bundle
<?php // app/AppKernel.php public function registerBundles() { $bundles = array( // ... new IMAG\LdapBundle\IMAGLdapBundle(), ); }
配置security.yml
注意
示例
security.yml
文件位于Bundle中的./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"
实现登录
只需将隐藏标签添加到登录表单中,并将id设置为ldap_authenticate
。
<input type="hidden" name="_csrf_token" value="{{ csrf_token('ldap_authenticate') }}">
实现注销
只需创建一个具有注销目标的链接。
<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)。如果您想覆盖用户(例如,如凭据、角色等),则必须创建一个新的提供者并重写此方法。