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

基于Apache+PHP的内网Web应用Active Directory直通认证求助

给你一套AD直通认证(SSO)的落地步骤

第一步:搞定Ubuntu主机/容器的Kerberos环境

  • 先装依赖包:apt-get install krb5-user libsasl2-modules-gssapi-mit libapache2-mod-auth-gssapi php-ldap
  • 编辑/etc/krb5.conf,把占位符换成你的AD实际信息:
    [libdefaults]
        default_realm = YOUR_AD_DOMAIN.COM  # 大写的AD域,比如CORP.LOCAL
        dns_lookup_realm = true
        dns_lookup_kdc = true
    [realms]
        YOUR_AD_DOMAIN.COM = {
            kdc = ad-dc.your-ad-domain.com  # AD域控制器的主机名/IP
            admin_server = ad-dc.your-ad-domain.com
        }
    [domain_realm]
        .your-ad-domain.com = YOUR_AD_DOMAIN.COM
        your-ad-domain.com = YOUR_AD_DOMAIN.COM
    
  • 去AD服务器生成并导出keytab文件:
    1. 用AD管理员账号执行:setspn -A HTTP/你的Web服务器域名.your-ad-domain.com AD服务账号名
    2. 导出keytab:ktpass /out http.keytab /princ HTTP/你的Web服务器域名.your-ad-domain.com@YOUR_AD_DOMAIN.COM /mapuser AD服务账号名@YOUR_AD_DOMAIN.COM /pass 服务账号密码 /crypto ALL /ptype KRB5_NT_PRINCIPAL
    3. 把http.keytab传到Ubuntu的/etc/apache2/目录,修改权限:chown www-data:www-data /etc/apache2/http.keytab && chmod 600 /etc/apache2/http.keytab

第二步:Apache配置GSSAPI认证触发点

  • 启用模块:a2enmod auth_gssapi
  • 在你的虚拟主机配置里添加一段规则(指定/sso-login作为SSO触发路径):
    <Location "/sso-login">
        AuthType GSSAPI
        AuthName "用Windows凭据登录"
        GssapiCredStore keytab:/etc/apache2/http.keytab
        GssapiAllowedMech krb5
        Require valid-user
    
        # 将认证后的用户名传递给PHP
        SetEnv REMOTE_USER %{REMOTE_USER}s
    </Location>
    
  • 重启Apache:容器内执行service apache2 restart,宿主机执行systemctl restart apache2

第三步:PHP端的两种实现方式

方式1:直接用Apache传递的REMOTE_USER(最简单)

用户访问/sso-login时,浏览器会自动弹出Windows凭据框(域内机器甚至自动提交),认证通过后Apache会把AD用户名(格式user@DOMAIN.COM)写入$_SERVER['REMOTE_USER'],直接拿来用即可:

session_start();
if (isset($_SERVER['REMOTE_USER'])) {
    $adUser = $_SERVER['REMOTE_USER'];
    // 如需短用户名可拆分:$shortName = explode('@', $adUser)[0];
    // 这里编写你的应用登录逻辑,比如存储会话、验证权限
    $_SESSION['current_user'] = $adUser;
    header('Location: /你的应用首页');
    exit;
} else {
    // 认证失败跳回普通登录页
    header('Location: /login');
    exit;
}

方式2:用ldap_sasl_bind手动绑定(适合不依赖Apache认证的场景)

如果要在PHP中自行完成SASL绑定,确保php-ldap模块已安装即可,代码示例:

session_start();
if (!isset($_SESSION['logged_in'])) {
    $ldapConn = ldap_connect('ldap://你的AD域控制器地址');
    ldap_set_option($ldapConn, LDAP_OPT_PROTOCOL_VERSION, 3);
    ldap_set_option($ldapConn, LDAP_OPT_REFERRALS, 0);

    // 使用GSSAPI进行SASL绑定
    $bindOk = ldap_sasl_bind($ldapConn, null, null, 'GSSAPI');

    if ($bindOk) {
        // 获取当前认证的用户信息
        $whoami = ldap_whoami($ldapConn);
        preg_match('/u:(.*)/', $whoami, $matches);
        $adUser = $matches[1] ?? '';
        if ($adUser) {
            $_SESSION['current_user'] = $adUser;
            $_SESSION['logged_in'] = true;
            header('Location: /你的应用首页');
            exit;
        }
    }
    // 绑定失败跳转到SSO触发页面
    header('Location: /sso-login');
    exit;
}

第四步:客户端配置要求

  • Windows客户端必须加入AD域,且当前用户已登录AD账号
  • 浏览器需允许发送Kerberos凭据:
    • Chrome/Edge:开启chrome://flags/#negotiate-delegate-by-default,或通过组策略添加信任站点
    • Firefox:在about:config中设置network.negotiate-auth.trusted-uris为你的Web应用域名

排错小技巧

  • 测试Kerberos有效性:在Ubuntu主机执行kinit HTTP/你的Web服务器域名.your-ad-domain.com,能成功获取票据说明keytab配置正确
  • 查看Apache日志:tail -f /var/log/apache2/error.log,里面会记录认证失败的具体原因
  • 开启PHP错误日志,排查ldap_sasl_bind返回的错误信息

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 09:43:17