jotaelesalinas/laravel-adminless-ldap-auth

在 Laravel 中通过无管理员 LDAP 服务器验证用户

v0.6.3 2021-02-24 09:27 UTC

README

在 Laravel 中通过无管理员 LDAP 服务器验证用户

Latest Version on Packagist Total Downloads Software License

重要:此身份验证包的使用场景非常具体

  • 此包只做一件事:验证用户凭据与 LDAP 服务器。
  • 无法在 Laravel 应用程序中创建/修改/删除用户。
  • 用户管理在 LDAP 服务器中完成。

安装

您需要一个现有的 Laravel 项目。在其文件夹中,输入

composer require jotaelesalinas/laravel-adminless-ldap-auth

您可能会收到一个错误,表示无法解决安装包的需求。这通常是由于 adldap2/adldap2 依赖于 Laravel 也需要的一些不同版本的包所导致。此问题通常通过添加选项 -W(或 --update-with-all-dependencies)来解决,但请注意,这可能会引起问题。

composer require jotaelesalinas/laravel-adminless-ldap-auth -W

继续配置。如果不正确配置,则该包将无法正常工作。

配置

关于最重要的 .env 变量的说明

  • LDAP_USER_SEARCH_ATTRIBUTE:在 LDAP 服务器中唯一标识用户的属性名称,例如 uidmailsAMAccountName。此属性的值是用户需要在登录表单中输入的标识符(当然还有密码)。

  • LDAP_USER_BIND_ATTRIBUTE:在 LDAP 服务器中用作唯一标识符的属性名称,例如 uidcn。此值将来自 LDAP 服务器返回的用户属性。

  • AUTH_USER_KEY_FIELD:将唯一标识 Auth 用户的属性名称。默认名称为 username,值从 LDAP 用户属性 LDAP_USER_SEARCH_ATTRIBUTE 中读取。

请参阅库工作原理的解释,以更好地理解不同变量的背后的逻辑。

将变量添加到 .env

您需要您的 LDAP 管理员的协助才能正确设置这些选项。

LDAP_SCHEMA=OpenLDAP                # Has to be one of these:
                                    #  - OpenLDAP
                                    #  - FreeIPA
                                    #  - ActiveDirectory
LDAP_HOSTS=ldap.forumsys.com        # Your LDAP server
LDAP_BASE_DN=dc=example,dc=com      # base distinguished name
LDAP_USER_SEARCH_ATTRIBUTE=uid      # field by which your users are identified in the LDAP server
LDAP_USER_BIND_ATTRIBUTE=uid        # field by which your users are binded to the LDAP server
LDAP_USER_FULL_DN_FMT=${LDAP_USER_BIND_ATTRIBUTE}=%s,${LDAP_BASE_DN}
                                    # full user distinguished name to be used with sprintf:
                                    # %s will be replaced by $user->${LDAP_USER_BIND_ATTRIBUTE}
LDAP_CONNECTION=default             # which configuration to use from config/ldap.php

这只是几个选项,使此示例工作所需。还有更多选项在 config/ldap.php 中。

另外,添加唯一标识您的 Auth 用户的属性名称

AUTH_USER_KEY_FIELD=username

您可以将 AUTH_USER_KEY_FIELD 的值更改为您想要的任何值,例如 idemailphonenumber,但您不必真的这么做。

针对 Windows ActiveDirectory 用户

基于一些反馈,此配置可能适用于您(我无法保证它会适用)

LDAP_SCHEMA=ActiveDirectory
LDAP_USER_SEARCH_ATTRIBUTE=sAMAccountName
LDAP_USER_BIND_ATTRIBUTE=cn

使用 Apache Directory 进行测试

我已经能够使用 dwimberger/ldap-ad-it docker 映像和 Apache Directory 安装来测试 ActiveDirectory。感谢 James Hamilton 提供此 视频

我知道它与 Windows 的 RSAT ActiveDirectory 不同,但我已经测试过的就是这些。

以下是必须更改才能使其工作的 .env 变量

LDAP_SCHEMA=ActiveDirectory
LDAP_HOSTS=127.0.0.1
LDAP_PORT=10389
LDAP_BASE_DN=ou=users,dc=wimpi,dc=net

此外,我不得不修改代码,在尝试搜索用户之前先连接到 LDAP 服务器。我认为这可能是大多数人在尝试使用 AD 与库结合时遇到的实际问题。

修改 config/auth.php

使用新安装的 adminless_ldap 驱动添加一个新的 LDAP 提供商

'providers' => [
    'ldap' => [
        'driver' => 'adminless_ldap',
    ],
],

如果您想的话,可以删除 users 提供商。或者只注释它。不要让未使用的代码悬挂在那里。

修改 web 守卫以使用新的 ldap 提供商

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'ldap',
    ],
],

如果您不需要它,请删除 api 守卫。或者至少注释它。

重要! 创建此新条目

'auth_user_key' => env('AUTH_USER_KEY_FIELD', null),

发布 Adldap 和 AdldapAuth 的配置文件

php artisan vendor:publish --provider="Adldap\Laravel\AdldapServiceProvider"
php artisan vendor:publish --provider="Adldap\Laravel\AdldapAuthServiceProvider"

config/ldap.php 中配置 LDAP 连接

再次,您将需要您的 LDAP 管理员的协助。请参阅下面的注释。

'connections' => [

    // here, in theory, we should leave `default` untouched and create a new connection
    // (and change `LDAP_CONNECTION` in `.env` accordingly)
    // but I wasn't able to make the underlying Adldap package work with any connection
    // other than `default`, so we will modify the default connection directly

    'default' => [
        'auto_connect' => env('LDAP_AUTO_CONNECT', false),

        'connection' => Adldap\Connections\Ldap::class,

        'settings' => [

            // replace this line:
            // 'schema' => Adldap\Schemas\ActiveDirectory::class,
            // with this:
            'schema' => env('LDAP_SCHEMA', '') == 'OpenLDAP' ?
                            Adldap\Schemas\OpenLDAP::class :
                            ( env('LDAP_SCHEMA', '') == 'FreeIPA' ?
                                Adldap\Schemas\FreeIPA::class :
                                Adldap\Schemas\ActiveDirectory::class ),

            // remove the default values of these options:
            'hosts' => explode(' ', env('LDAP_HOSTS', '')),
            'base_dn' => env('LDAP_BASE_DN', ''),
            'username' => env('LDAP_ADMIN_USERNAME', ''),
            'password' => env('LDAP_ADMIN_PASSWORD', ''),

            // and talk to your LDAP administrator about these other options.
            // do not modify them here, use .env!
            'account_prefix' => env('LDAP_ACCOUNT_PREFIX', ''),
            'account_suffix' => env('LDAP_ACCOUNT_SUFFIX', ''),
            'port' => env('LDAP_PORT', 389),
            'timeout' => env('LDAP_TIMEOUT', 5),
            'follow_referrals' => env('LDAP_FOLLOW_REFERRALS', false),
            'use_ssl' => env('LDAP_USE_SSL', false),
            'use_tls' => env('LDAP_USE_TLS', false),

        ],
    ],
],

config/ldap_auth.php 中配置 LDAP 认证

告诉 Adldap 库如何在您的 LDAP 服务器中搜索和绑定用户。

重要! 不要忘记添加 user_format 条目。

'identifiers' => [
    // ... other code ...

    'ldap' => [
        'locate_users_by' => env('LDAP_USER_SEARCH_ATTRIBUTE', ''),
        'bind_users_by' => env('LDAP_USER_BIND_ATTRIBUTE', ''),
        'user_format' => env('LDAP_USER_FULL_DN_FMT', ''),
    ],

    // ... other code ...
],

并告诉新的身份验证提供商,您希望从 LDAP 用户条目中导入哪些字段到您的 Auth 用户中,每次登录成功时都会导入。

'sync_attributes' => [
    // 'field_in_local_user_model' => 'attribute_in_ldap_server',
    env('AUTH_USER_KEY_FIELD', null) => env('LDAP_USER_SEARCH_ATTRIBUTE', null),
    'name' => 'cn',
    'email' => 'mail',
    'phone' => 'telephonenumber',
],

用法

就这样!现在您应该可以使用 Laravel 的内置身份验证 来执行所有与身份验证相关的任务,例如 Auth::check()Auth::attempt()Auth::user() 等。

您可以在 tinker 中尝试

php artisan optimize:clear
php artisan tinker

如果您收到错误消息,说明不允许写入 /path/to/folder/.config/psysh,请尝试在您的 .env 中添加此行

XDG_CONFIG_HOME=.

运行这些说明以实时测试应用程序

Auth::guest()
=> true
Auth::check()
=> false
Auth::user()
=> null
Auth::id()
=> null

Auth::attempt(['username' => 'einstein', 'password' => ''])
=> false

Auth::attempt(['username' => 'einstein', 'password' => 'qwerty'])
=> false

Auth::attempt(['username' => 'einstein', 'password' => 'password'])
=> true

Auth::guest()
=> false
Auth::check()
=> true
Auth::user()
=> JotaEleSalinas\AdminlessLdap\LdapUser {
     username: "einstein",
     name: "Albert Einstein",
     email: "einstein@ldap.forumsys.com",
     phone: "314-159-2653",
   }
Auth::id()
=> "einstein"

Auth::logout()
=> null
Auth::check()
=> false
Auth::user()
=> null

请记住,在公共测试 LDAP 服务器中您有以下这些用户:einsteinnewtontesla。密码对所有用户都是 password

如果您想查看 LDAP 服务器中每个用户可用的属性,请在 Tinker 中运行此命令

$lh = new JotaEleSalinas\AdminlessLdap\LdapHelper(config('ldap_auth'))
=> JotaEleSalinas\AdminlessLdap\LdapHelper
$lh->retrieveLdapAttribs('einstein', 'password')
=> [
     "userpassword" => "{sha}W6ph5Mm5Pz8GgiULbPgzG37mj9g=",
     "cn" => "Albert Einstein",
     "sn" => "Einstein",
     "uid" => "einstein",
     "mail" => "einstein@ldap.forumsys.com",
     "telephonenumber" => "314-159-2653",
     "dn" => "uid=einstein,dc=example,dc=com",
   ]

如果您觉得这个包有用,请给它加星。它帮了您一天吗?您从中赚钱了吗?请考虑 赞助我

登录 UI(路由、控制器、视图)

如果您想了解如何构建适合此特定 adminless LDAP 系统的登录 UI,您可以阅读 登录 UI 指南

待办事项

  • 测试 — 进行中
  • ActiveDirectory 的说明 — 需要帮助,我没有访问任何 AD 服务器
  • 我们必须触发登录尝试、成功、失败、注销等事件吗?或者它们在其他地方触发?
  • 添加构建登录 UI 的说明
  • Illuminate\Auth\GenericUser 上扩展 LdapUser
  • 上传到 packagist
  • 为 Packagist 设置 GitHub Hook 以自动化新版本

贡献

请参阅 CONTRIBUTINGCODE_OF_CONDUCT 以获取详细信息。

安全

如果您发现任何安全相关的问题,请通过电子邮件 jotaelesalinas@example.com 而不是使用问题跟踪器。

鸣谢

赞助

这个包帮了您一天吗?您从中赚钱了吗?通过 赞助我 来回馈!

许可和免责声明

本项目的许可证为MIT。请参阅许可证文件获取更多信息。

本文档中显示的配置使用了公开可用的测试LDAP服务器。本软件包的作者与该服务器没有任何关联,也不对与该服务器相关的任何事项承担责任或承担任何形式的法律责任。