You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 5.8:如何实现数据库与Active Directory混合用户认证

嘿,我之前刚好在Laravel 5.8里折腾过类似的混合认证需求,给你梳理下具体的实现步骤,亲测可行:

整体思路

Laravel的认证系统本身是高度可扩展的,我们可以在默认的认证流程里加入分支逻辑:先尝试本地数据库用户认证,失败后再尝试Active Directory(AD)认证;对于首次通过AD验证的用户,自动将其信息导入本地数据库,后续登录时可以复用本地记录(也可以每次都校验AD密码,看你的需求)。

具体实现步骤

1. 安装AD认证依赖

Laravel生态里常用的AD集成包是adldap2/adldap2-laravel,注意要选适配Laravel 5.8的版本(v5.x系列),执行命令:

composer require adldap2/adldap2-laravel:5.2.*

然后发布AD的配置文件:

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

2. 配置AD服务器连接

打开生成的config/adldap.php文件,根据你的实际AD环境修改配置项:

'connections' => [
    'default' => [
        'auto_connect' => false,
        'connection' => Adldap\Connections\Ldap::class,
        'settings' => [
            'schema' => Adldap\Schemas\ActiveDirectory::class,
            'account_prefix' => 'YOUR_DOMAIN\\', // 比如你的域是TEST,就填TEST\\
            'account_suffix' => '@your-domain.com',
            'hosts' => ['ad.your-domain.com'], // AD服务器地址
            'port' => 389, // 默认LDAP端口,用SSL的话改成636
            'timeout' => 5,
            'base_dn' => 'DC=your-domain,DC=com', // AD的基准DN
            'username' => 'ad-admin@your-domain.com', // 有查询权限的AD账号
            'password' => 'your-admin-password',
        ],
    ],
],

3. 自定义登录逻辑(核心)

我们需要重写默认的登录控制器逻辑,让系统支持双重认证路径。打开app/Http/Controllers/Auth/LoginController.php,添加/修改以下代码:

use Illuminate\Http\Request;
use Adldap\Laravel\Facades\Adldap;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Str;

// 重写认证方法
public function authenticate(Request $request)
{
    // 先做登录参数验证
    $this->validateLogin($request);

    // 第一步:尝试本地数据库用户认证
    if (Auth::attempt($request->only('email', 'password'))) {
        return $this->sendLoginResponse($request);
    }

    // 第二步:本地认证失败,尝试AD认证
    try {
        // 根据邮箱在AD中查找用户
        $adUser = Adldap::search()->where('mail', '=', $request->email)->first();
        
        // 验证AD用户的密码是否正确
        if ($adUser && Adldap::auth()->attempt($adUser->getAccountName(), $request->password)) {
            // 检查本地数据库是否已有该用户记录
            $localUser = \App\User::where('email', $request->email)->first();
            
            if (!$localUser) {
                // 自动创建本地用户记录
                $localUser = \App\User::create([
                    'name' => $adUser->getCommonName(),
                    'email' => $adUser->getEmail(),
                    // 生成随机密码占位(AD用户不会用到本地密码)
                    'password' => bcrypt(Str::random(16)),
                    // 可选:添加标记字段区分AD用户和本地用户
                    'is_ad_user' => true,
                ]);
            }
            
            // 登录本地用户
            Auth::login($localUser);
            return $this->sendLoginResponse($request);
        }
    } catch (\Exception $e) {
        // AD连接或验证失败,直接返回登录错误
        return $this->sendFailedLoginResponse($request);
    }

    // 两种认证方式都失败,返回错误
    return $this->sendFailedLoginResponse($request);
}

4. 可选:添加AD用户标记字段

如果需要区分本地用户和AD用户,可以给users表加一个布尔字段:

  1. 生成迁移文件:
php artisan make:migration add_is_ad_user_to_users_table --table=users
  1. 编辑迁移文件:
public function up()
{
    Schema::table('users', function (Blueprint $table) {
        $table->boolean('is_ad_user')->default(false);
    });
}

public function down()
{
    Schema::table('users', function (Blueprint $table) {
        $table->dropColumn('is_ad_user');
    });
}
  1. 执行迁移:
php artisan migrate

5. 测试验证

  • 本地用户:用之前注册的账号登录,应该正常进入系统;
  • AD用户:用AD的邮箱和密码登录,第一次登录会自动在本地数据库创建用户记录,后续登录会自动完成认证。
关键注意事项
  • 确保应用服务器和AD服务器网络连通,端口389(或636)开放;
  • AD用户的邮箱字段要和本地用户的email字段对应,如果AD里用的是其他标识(比如samaccountname),要调整代码里的搜索条件;
  • AD用户的本地密码只是占位,永远不会被使用,所以可以随便生成;
  • 如果需要强制AD用户每次登录都校验AD密码(避免本地账号被篡改),可以修改逻辑,每次AD用户登录时都先验证AD密码,再登录本地用户。

内容的提问来源于stack exchange,提问作者ayobamilaye

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:43:38