Laravel集成AD LDAP登录遇Nginx 403 Forbidden问题求助
问题背景
我正在基于Laravel实现Active Directory(AD)LDAP登录功能,已完成以下配置:
- 编写了LDAP认证控制器逻辑,通过AD验证用户凭据并关联本地
userRole表的权限 - 配置了AD服务器地址、LDAP绑定DN,创建了登录表单的GET/POST路由
- 修改了
.env和config/app.php的协议配置,关闭了secure protocol - 创建
userRole表用于邮箱匹配与权限校验 - 调整
config/auth.php的guards和providers,指定用户模型为UserRole
当前核心问题:访问应用根路径/时触发Nginx 403 Forbidden错误;根目录存在php/html文件时可正常访问,移除后就会报错,无法进入Laravel应用并自动跳转至登录页。
代码片段
LdapAuthController.php
class LdapAuthController extends Controller { public function ldapLogin(Request $request) { if ($request->isMethod('post')) { if (isset($request->username) && isset($request->password)) { $adServer = "ldap://domaincontroller.mydomain.com"; $ldap = ldap_connect($adServer); $username = $request->username; $password = $request->password; $ldaprdn = 'mydomain' . "\\" . $username; ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0); $bind = @ldap_bind($ldap, $ldaprdn, $password); if ($bind) { $filter = "(sAMAccountName=$username)"; $result = ldap_search($ldap, "dc=MYDOMAIN,dc=COM", $filter); if ($result) { $info = ldap_get_entries($ldap, $result); $email = $info[0]["mail"][0]; $userRole = UserRole::where('email', $email)->first(); if ($userRole) { session(['user_role' => $userRole->role]); } } else { return back()->with('error', 'LDAP search failed'); } @ldap_close($ldap); return redirect()->route('dashboard'); } else { return back()->with('error', 'Invalid email address / password'); } } } else { return view('auth.login'); } } }
web.php
Route::get('/login', function () { return view('auth.ldap-login-form'); })->name('login'); Route::post('/login', [LdapAuthController::class, 'ldapLogin'])->name('login.submit'); Route::group(['namespace' => 'App\Http\Controllers'], function () { Route::group(['middleware' => ['guest']], function () { Route::post('/ldap-login', [LdapAuthController::class, 'ldapLogin'])->name('ldap-login'); }); Route::group(['middleware' => ['auth']], function () { Route::get('/logout', 'LogoutController@logout')->name('logout.logout'); Route::group(['middleware' => ['checkUserRole:admin']], function () { // 管理员路由 }); }); });
config/auth.php
'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], ], 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\Models\UserRole::class, ], ],
解决方案
一、先解决Nginx 403错误
这是因为Nginx没有正确将请求转发到Laravel的入口文件,或者目录配置有误:
修正Nginx站点配置
确保配置文件中root指向Laravel项目的public目录,并且配置try_files规则让所有请求经过index.php处理:server { listen 80; server_name your-domain.com; root /path/to/your/laravel-project/public; index index.php index.html index.htm; location / { try_files $uri $uri/ /index.php?$query_string; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.2-fpm.sock; # 根据你的PHP版本调整 } location ~ /\.ht { deny all; } }配置完成后重启Nginx:
sudo systemctl restart nginx修复目录权限
确保Nginx进程用户(通常是www-data)拥有Laravel目录的读写权限:sudo chown -R www-data:www-data /path/to/your/laravel-project sudo chmod -R 755 /path/to/your/laravel-project sudo chmod -R 775 /path/to/your/laravel-project/storage /path/to/your/laravel-project/bootstrap/cache
二、完善Laravel路由与认证逻辑
添加根路径路由
在web.php中配置根路径的跳转规则,未登录用户自动跳转到登录页:Route::get('/', function () { return Auth::check() ? redirect()->route('dashboard') : redirect()->route('login'); });修正LDAP认证的Auth登录逻辑
当前代码仅存储了user_role会话,但未让Laravel的Auth系统识别用户登录,导致auth中间件无法生效。修改LdapAuthController中绑定成功后的代码:if ($bind) { $filter = "(sAMAccountName=$username)"; $result = ldap_search($ldap, "dc=MYDOMAIN,dc=COM", $filter); if ($result) { $info = ldap_get_entries($ldap, $result); $email = $info[0]["mail"][0]; $userRole = UserRole::where('email', $email)->first(); if ($userRole) { // 让Laravel Auth系统登录该用户 Auth::login($userRole); session(['user_role' => $userRole->role]); } else { return back()->with('error', '无系统访问权限,请联系管理员'); } } else { return back()->with('error', 'LDAP搜索失败'); } @ldap_close($ldap); return redirect()->route('dashboard'); }同时确保
UserRole模型继承Laravel的用户基类:namespace App\Models; use Illuminate\Foundation\Auth\User as Authenticatable; class UserRole extends Authenticatable { protected $table = 'user_roles'; }清理重复路由
移除web.php中重复的/ldap-login路由,避免路由冲突:// 删除这段重复路由 Route::group(['middleware' => ['guest']], function () { Route::post('/ldap-login', [LdapAuthController::class, 'ldapLogin'])->name('ldap-login'); });
三、清除缓存验证
执行以下命令清除Laravel缓存,确保配置生效:
php artisan cache:clear php artisan config:clear php artisan route:clear
内容的提问来源于stack exchange,提问作者peterpan26
相关产品推荐
相关产品推荐

