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

IIS 10+Laravel 5.4配置SSO及登录表单共存问题求助

解决IIS下Laravel同时支持表单登录与Windows SSO认证的问题

老哥,刚接手IIS项目就碰这种认证兼容问题确实闹心,我来帮你一步步捋清楚。你的核心需求是同时搞定内网自动SSO(Windows认证)和VPN场景的表单登录,现在开了Windows Auth后弹窗口还登不上,咱们从IIS配置、PHP环境、Laravel逻辑三层入手解决:

一、先把IIS的认证配置捋顺

你之前直接关了匿名认证是关键错误——要同时支持两种登录,站点级别得同时开启匿名认证和Windows认证,然后给不同路由单独配置认证规则,不然表单登录的路由会被Windows Auth强制拦截。

1. 调整Windows认证提供者顺序

在IIS站点的「Windows Authentication」设置里,打开「Providers」,把Negotiate拖到NTLM前面。IE11在内网环境优先用Negotiate做Kerberos自动认证,能实现无感知SSO;VPN环境Kerberos失效时,会自动 fallback到NTLM(需要手动输账号,但至少能登录)。

2. 用web.config给路由分配置

在站点根目录的web.config里添加路由级别的认证规则,比如:

<!-- SSO专属路由:禁用匿名,启用Windows认证 -->
<location path="sso-login">
  <system.webServer>
    <security>
      <authentication>
        <anonymousAuthentication enabled="false" />
        <windowsAuthentication enabled="true" />
      </authentication>
    </security>
  </system.webServer>
</location>

<!-- 表单登录路由:禁用Windows认证,保留匿名 -->
<location path="login">
  <system.webServer>
    <security>
      <authentication>
        <anonymousAuthentication enabled="true" />
        <windowsAuthentication enabled="false" />
      </authentication>
    </security>
  </system.webServer>
</location>

这样不同路由走不同认证逻辑,就不会互相冲突了。

二、让PHP能拿到Windows Auth的用户信息

你说$_SERVER里没有AUTH_USER,是因为IIS默认不会把Windows认证的用户信息传递给PHP的FastCGI进程,得手动配置环境变量:

方法1:通过IIS图形界面配置

  1. 打开IIS管理器,找到「FastCGI设置」
  2. 找到你的PHP应用池(比如PHP_via_FastCGI),右键「编辑」
  3. 切换到「环境变量」标签,添加两个变量:
    • 名称:AUTH_USER,值:{AUTH_USER}
    • 名称:AUTH_PASSWORD,值:{AUTH_PASSWORD}

方法2:直接在web.config里加

如果嫌图形界面麻烦,直接在web.config的PHP handler节点里加环境变量:

<handlers>
  <add name="PHP_via_FastCGI" path="*.php" verb="GET,HEAD,POST" modules="FastCgiModule" scriptProcessor="C:\PHP\php-cgi.exe" resourceType="Either" requireAccess="Script">
    <environmentVariables>
      <add name="AUTH_USER" value="{AUTH_USER}" />
      <add name="AUTH_PASSWORD" value="{AUTH_PASSWORD}" />
    </environmentVariables>
  </add>
</handlers>

配置完重启IIS,PHP就能拿到$_SERVER['AUTH_USER']了,格式一般是DOMAIN\username,正好给adldap做验证。

三、Laravel里实现双认证逻辑

现在要写个分支逻辑:内网用户走SSO自动登录,VPN用户走表单登录。

1. 新增SSO登录路由

在routes/web.php里加:

// SSO自动登录路由
Route::get('/sso-login', 'Auth\LoginController@ssoLogin')->name('sso.login');
// 原表单登录路由保留
Route::get('/login', 'Auth\LoginController@showLoginForm')->name('login');
Route::post('/login', 'Auth\LoginController@login');

2. 在LoginController里写SSO逻辑

public function ssoLogin()
{
    // 检查是否有Windows认证的用户信息
    if (isset($_SERVER['AUTH_USER'])) {
        // 拆分域名和用户名(格式:DOMAIN\username)
        [$domain, $username] = explode('\\', $_SERVER['AUTH_USER'], 2);
        
        // 用adldap验证用户身份(不需要密码,因为Windows Auth已经验证过)
        if (Adldap::auth()->attempt($username, null, $bindAsUser = false)) {
            // 查找或自动创建Laravel用户
            $user = User::firstOrCreate(
                ['username' => $username],
                [
                    'name' => Adldap::search()->users()->find($username)->getCommonName(),
                    'email' => Adldap::search()->users()->find($username)->getEmail(),
                    // 可以设置一个随机密码,因为SSO用户不需要用密码登录
                    'password' => bcrypt(str_random(16)),
                ]
            );
            
            // 自动登录用户
            Auth::login($user);
            return redirect()->intended('/dashboard');
        }
        
        return abort(403, 'LDAP身份验证失败');
    }
    
    // 如果没有Windows Auth信息,跳转到表单登录页
    return redirect()->route('login');
}

四、IE11的兼容性配置

内网用户要实现无感知SSO,得确保IE11的设置正确:

  • 把你的站点加入「本地Intranet」区域(工具→Internet选项→安全→本地Intranet→站点→添加)
  • 开启自动登录:「本地Intranet」→「自定义级别」→「用户验证」→选择「自动登录到Intranet区域」

这样内网用户访问/sso-login时,IE会自动用当前Windows账号完成认证,不会弹登录窗口;VPN用户访问/login时,走原来的表单登录流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:36:39