mc9629 / laravel-adminless-ldap-auth-memberof

在Laravel中验证用户以对抗无管理员的LDAP服务器

dev-master / 1.0.x-dev 2023-04-21 15:43 UTC

This package is not auto-updated.

Last update: 2024-09-21 20:43:50 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 提供程序。或者只注释掉它。不要让未使用的代码悬挂在那里。

修改网络守卫以使用新的 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",
   ]

此包有用吗?给它一个星。它帮了您的忙吗?您从中获利了吗?请考虑 赞助我

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

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

待办事项

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

贡献

请参阅 贡献行为准则 以获取详细信息。

安全性

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

鸣谢

赞助

这个包帮了您的忙吗?您从中获利了吗?通过 赞助我 来回馈!

许可和免责声明

MIT 许可证 (MIT)。请参阅 许可文件 以获取更多信息。

此文档中显示的配置使用了 公开可用的测试 LDAP 服务器。此包的作者与它没有任何联系,也不对此负责或承担任何责任。