如何通过NTLM在LDAP/Active Directory中验证用户凭据?
问题:Apache PHP服务器联动NTLM与Active Directory LDAP权限控制
我有一台Apache PHP服务器,想利用现有Active Directory实现权限控制,选择NTLM自动认证Windows用户,这部分已正常工作,能获取用户名及NTLM挑战响应。
我通过服务账号使用PHP LDAP函数与Active Directory通信,目前已能查询用户组、验证用户名是否存在,但无法以用户身份绑定来验证密码:
$success = @ldap_bind($ad, "$username@$domain}", $password) or die('Could not bind to AD.');
我可以使用明文密码完成绑定,但仅持有NTLM Response Security Buffer,没有明文密码。
请问是否可以联动NTLM与LDAP?具体该如何操作?PHP的ldap_bind是否不支持NTLM?
我了解到可将挑战信息与用户NTLM响应作为“NETLOGON_NETWORK_INFO”传输,但未找到相关实现文档;还看到一个Laravel库声称能实现该功能,但查看代码后发现其仍是使用需要明文密码的@ldap_bind,与我已测试的内容一致。我的问题和Stack Overflow上一个未解答的问题类似,但目前关联LDAP与NTLM的资料极少。
以下是服务器上已有的NTLM实现代码:
$headers = apache_request_headers(); if (@$_SERVER['HTTP_VIA'] != NULL) { //echo "Proxy bypass!"; } elseif(!isset($headers['Authorization']) || $headers['Authorization'] == NULL) { header( "HTTP/1.0 401 Unauthorized" ); header( "WWW-Authenticate: NTLM" ); exit; } if(isset($headers['Authorization']) && substr($headers['Authorization'],0,5) == 'NTLM ') { $chaine = substr($headers['Authorization'], 5); $chained64 = base64_decode($chaine); if(ord($chained64[8]) == 1) { $retAuth = "NTLMSSP".chr(000).chr(002).chr(000).chr(000).chr(000).chr(000).chr(000).chr(000); $retAuth .= chr(000).chr(040).chr(000).chr(000).chr(000).chr(001).chr(130).chr(000).chr(000); $retAuth .= chr(000).chr(002).chr(002).chr(002).chr(000).chr(000).chr(000).chr(000).chr(000); $retAuth .= chr(000).chr(000).chr(000).chr(000).chr(000).chr(000).chr(000); $retAuth64 = trim(base64_encode($retAuth)); header( "HTTP/1.0 401 Unauthorized" ); header( "WWW-Authenticate: NTLM $retAuth64" ); exit; } if(ord($chained64[8]) == 3) { //LM Response Security Buffer: $lenght_LMRSB = (ord($chained64[15])*256 + ord($chained64[14])); $offset_LMRSB = (ord($chained64[17])*256 + ord($chained64[16])); $LMRSB = str_replace("\0","",substr($chained64, $offset_LMRSB, $lenght_LMRSB)); //NTLM Response Security Buffer: $lenght_NTLMRSB = (ord($chained64[23])*256 + ord($chained64[22])); $offset_NTLMRSB = (ord($chained64[25])*256 + ord($chained64[24])); $NTLMRSB = str_replace("\0","",substr($chained64, $offset_NTLMRSB, $lenght_NTLMRSB)); //Domain: $lenght_domain = (ord($chained64[31])*256 + ord($chained64[30])); $offset_domain = (ord($chained64[33])*256 + ord($chained64[32])); $domain = str_replace("\0","",substr($chained64, $offset_domain, $lenght_domain)); //Login: $lenght_login = (ord($chained64[39])*256 + ord($chained64[38])); $offset_login = (ord($chained64[41])*256 + ord($chained64[40])); $login = str_replace("\0","",substr($chained64, $offset_login, $lenght_login)); echo "$LMRSB<br>"; echo "$NTLMRSB<br>"; //HERE i would like to verify credentials against my active directory before accepting the username as a real logged user $_SESSION["utilisateur"] = $login; } }
内容的提问来源于stack exchange,提问作者Neil
相关产品推荐
相关产品推荐

