PHP Single Sign On using NTLMv2

I have a nginx web server using php-fpm to execute a script, and I want to get the NTLMv2 credentials for the client viewing the server. I have a proxy server on my local network to authenticate my users. The question is, how do I authenticate the nginx server, or does PHP get my user credentials using NTLMv2 and pass the information back to me? I obviously need to know their username, at least to make sure the client gets the correct credentials on the system.

I am fine with connecting up the proxy server, when, for example, I go to /login.php while it sends client information to the server about the client, for example, the username found in a message of type 3, I could save this information in flow their session and use it from this point.


I have a Linux server running nginx, PHP and SQLite on a local network. Computers connecting to this server all run on Windows, using Windows Login on the network. Logging in uses NTLMv2 authentication and access to websites outside the network through a proxy server, which all clients must go through to establish a connection to an external website. I want to use NTLMv2 authentication information to log in to a LAN web server. Any suggestions on how I can do this?

+4
source share
1 answer

I think the easiest way to achieve something like this is to simulate NTLMv2 authentication on the nginx server, redirect proxy requests and check the response. I cannot reproduce your setup, so the code below is not verified, but it should work, or it should help a little.

<?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 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 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) } } } } }?> 

I used this link for the NTLM protocol: http://davenport.sourceforge.net/ntlm.html

Hope this helps you. Feel free to comment.

+5
source

All Articles