2013-04-15 4 views
4

У меня есть веб-сервер nginx, используя php-fpm для выполнения скрипта, и я хочу получить учетные данные NTLMv2 для клиента, просматривающего сервер. У меня есть прокси-сервер в моей локальной сети для аутентификации моих пользователей. Вопрос в том, как сделать аутентификацию сервера nginx, или PHP получить учетные данные моих пользователей с помощью NTLMv2 и передать мне обратно информацию? Я, очевидно, должен знать их имя пользователя, по крайней мере, чтобы убедиться, что клиент получает правильные учетные данные в системе.PHP Single Sign On с использованием NTLMv2

Я в порядке с подключением вверх по прокси-серверу, когда, например, я перехожу на /login.php, если он передает информацию о клиенте обратно на сервер о клиенте, например пользователь имя, найденное в сообщении типа 3, я мог бы сохранить эту информацию в их сеансе и использовать ее с этой точки.

У меня есть сервер Linux, работающий под управлением nginx, PHP и SQLite в локальной сети. Компьютеры, подключающиеся к этому серверу, все работают на базе Windows, используя Windows Login в сети. Вход в систему использует проверку подлинности NTLMv2 и доступ к веб-сайтам за пределами сети через прокси-сервер, который все клиенты должны пройти, чтобы установить соединение с внешним веб-сайтом. Я хочу использовать информацию об аутентификации NTLMv2 для входа в веб-сервер локальной сети. Любые предложения о том, как я могу это сделать?

+1

Ничего себе, поиск Google для «nginx NTLMv2» уже имеет это на первой странице, и я задал этот вопрос только 7 минут назад. –

ответ

5

Я думаю, что самый простой способ добиться чего-то подобного - это имитировать аутентификацию NTLMv2 на сервере nginx, перенаправить запросы на прокси и проверить ответ. Я не могу воспроизвести вашу настройку, поэтому приведенный ниже код не проверяется, но он должен работать, или он должен вам немного помочь.

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

Я использовал эту ссылку протокола NTLM: http://davenport.sourceforge.net/ntlm.html

Я надеюсь, что это поможет. Не стесняйтесь комментировать.

+0

Спасибо за помощь, я попробую ваш код чуть позже! –

+0

В блоке типа 1 '$ response' никогда не устанавливается нигде, но используется. Поэтому я устанавливаю 'curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1);' и изменяет каждый '$ response' на' $ result'. Хотя, пока что не получается хорошо ... –

+0

@MarkTomlin Ой, прости меня. Вы пытались установить e_reporting в E_ALL? Возможно, вы можете использовать метод syslog() для печати некоторых отладочных материалов в вашем журнале, например $ message или $ result. – Max