使用NTLMv2的PHP单点登录
我有一个nginxweb服务器,使用php-fpm执行脚本,我想获取浏览服务器的客户端的NTLMv2凭据。我在本地网络中有一个代理服务器来验证我的用户。问题是,如何让nginx服务器进行身份验证,或者PHP使用NTLMv2获取用户的凭据并将信息传给我?我显然至少需要知道他们的用户名,以确保客户端在系统中获得正确的凭据 例如,当我转到/login.php时,我可以建立到代理服务器的上游连接,只要它将有关客户机的信息传递回服务器,例如关于客户机的信息,例如在Type-3消息中找到的用户名,我就可以将此信息保存在他们的会话中并从此开始使用它使用NTLMv2的PHP单点登录,php,proxy,nginx,single-sign-on,ntlmv2,Php,Proxy,Nginx,Single Sign On,Ntlmv2,我有一个nginxweb服务器,使用php-fpm执行脚本,我想获取浏览服务器的客户端的NTLMv2凭据。我在本地网络中有一个代理服务器来验证我的用户。问题是,如何让nginx服务器进行身份验证,或者PHP使用NTLMv2获取用户的凭据并将信息传给我?我显然至少需要知道他们的用户名,以确保客户端在系统中获得正确的凭据 例如,当我转到/login.php时,我可以建立到代理服务器的上游连接,只要它将有关客户机的信息传递回服务器,例如关于客户机的信息,例如在Type-3消息中找到的用户名,我就可以将
我有一个在局域网内运行nginx、PHP和SQLite的Linux服务器。使用Windows登录网络连接到此服务器的计算机都是基于Windows的。登录使用NTLMv2身份验证,并通过代理访问网络之外的网站,所有客户端都必须通过代理才能连接到外部网站。我想做的是,使用NTLMv2身份验证信息登录到LAN web服务器。有什么建议吗?我认为最简单的方法就是在nginx服务器上模拟NTLMv2身份验证,将请求重定向到代理并检查答案。 我无法复制您的设置,因此下面的代码未经测试,但它应该可以工作,或者应该会给您一些帮助
<?php
$headers = getallheaders() //Equivalent to apache_request_headers() to get the headers of the request.
if(!isset($headers['Authorization'])) //Check Authorization Header
{
header('HTTP/1.1 401 Unauthorized'); //Return Unauthorized Http-Header (NTLM protocol)
header('WWW-Authenticate: NTLM'); //Authenticcation Information (NTLM protocol)
}
else
{
if(substr($headers['Authorization'],0,4) == 'NTLM') //Check whether Authorization Header is valid
{
$message = base64_decode(substr($headers['Authorization'], 5)) //Get NTLM Message from Authrization header
if(substr($message, 0, 8) == "NTLMSSP\x00") //Check whether NTLM Message is valid
{
if($message[8] == "\x01") //Check whether it's type-1-NTLM Message
{
//$message holds the base64 encoded type-1-NTLM message
$ch = curl_init(); //Use cURL to connect to web via proxy
curl_setopt($ch, CURLOPT_URL, "http://www.google.com");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: '.$headers['Authorization']));
curl_setopt($ch, CURLOPT_PROXY, <Your Proxy Adress>);
curl_setopt($ch, CURLOPT_PROXYPORT, <Your Proxy Port>);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
$header = substr($result, 0, $info['header_size']);
$body = substr($result, $info['header_size'], $info['download_content_length']-$info['header_size']);
$c_headers = explode("\r\n", $header);
for($i = 0; $i < (count($c_headers) - 2); $i++)
{
header($c_headers[$i]);
if(substr($c_headers[$i], 0, 16) == "WWW-Authenticate")
{
//Thats your type-2-message header Format: WWW-Authenticate: NTLM <base64-type-2-message>
}
}
}
else if ($message[8] == "\x03") //Check whether it's type-3-NTLM Message
{
$ch = curl_init(); //Use cURL to connect to web via proxy
curl_setopt($ch, CURLOPT_URL, "http://www.google.com");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Authorization: '.$headers['Authorization']));
curl_setopt($ch, CURLOPT_PROXY, <Your Proxy Adress>);
curl_setopt($ch, CURLOPT_PROXYPORT, <Your Proxy Port>);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
curl_close($ch);
if($info['CURLINFO_HTTP_CODE'] == 200)
{
//Authenticated
//$msg holds the base64 encoded type-3-NTLM message (which includes username, domain, workstation)
}
}
}
}
}?>
Wow,谷歌搜索“nginx NTLMv2”已经在头版出现了,我7分钟前才问这个问题。谢谢你的帮助,我稍后会试用你的代码!在type-1块中,$response
从未设置在任何位置,但它被使用。所以我设置了curl\u setopt($ch,CURLOPT\u RETURNTRANSFER,1)
并将每个$response
更改为$result
。虽然,到目前为止,这还不太顺利…@MarkTomlin哦,对不起,我的错。您是否尝试将e_reporting设置为e_ALL?也许您可以使用syslog()方法在日志上打印一些调试内容,如$message或$result。目前,我正在使用echo打印这些信息,它工作正常。这就是我现在拥有的。另一件事,我在之前的笔记中没有提到的是,substr($headers['Authorization',0,5)='NTLM'
永远不会等于'NTLM',因为它也会包含空格,所以我将其设置为,0,4)
,这样就成功了。@MarkTomlin我很高兴听到它正在工作。如果没有测试代码的能力,很难发现容易犯的错误,但我希望我的答案能帮上忙。