基于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文件:
- 用AD管理员账号执行:
setspn -A HTTP/你的Web服务器域名.your-ad-domain.com AD服务账号名 - 导出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 - 把
http.keytab传到Ubuntu的/etc/apache2/目录,修改权限:chown www-data:www-data /etc/apache2/http.keytab && chmod 600 /etc/apache2/http.keytab
- 用AD管理员账号执行:
第二步: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应用域名
- Chrome/Edge:开启
排错小技巧
- 测试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
相关产品推荐
相关产品推荐

