2013-04-15 1 views
4

나는 스크립트 실행을 위해 php-fpm을 사용하는 nginx 웹 서버를 가지고 있으며 서버를 탐색하는 클라이언트의 NTLMv2 자격 증명을 얻고 싶습니다. 내 로컬 네트워크에 프록시 서버가있어 사용자를 인증합니다. 질문은, 어떻게해야합니까 nginx 서버를 인증, 또는 PHP는 NTLMv2를 사용하여 내 사용자의 자격 증명을 다시 날 정보를 전달합니까? 적어도 클라이언트가 시스템 내에서 올바른 자격 증명을 얻는 지 확인하려면 사용자 이름을 알아야합니다.NTLMv2를 사용하여 PHP Single Sign On

예를 들어 내가 /login.php에 갈 때 프록시 서버에 대한 업스트림 연결을 만들면 클라이언트에 대한 정보를 클라이언트 (예 : 사용자)에 전달할 수 있습니다. 이름이 Type-3 메시지에서 발견되면 세션 내에서이 정보를 저장하고 그 시점에서 사용할 수 있습니다.


로컬 영역 네트워크 내에서 nginx, PHP 및 SQLite를 실행하는 Linux 서버가 있습니다. 이 서버에 연결하는 컴퓨터는 모두 Windows 기반 네트워크를 사용하여 네트워크에 연결됩니다. 로그인은 NTLMv2 인증을 사용하고 모든 클라이언트가 외부 웹에 연결하기 위해 통과해야하는 프록시를 통해 네트워크 외부의 웹 사이트로 이동합니다. LAN 웹 서버에 로그인하기 위해 NTLMv2 인증 정보를 사용하고 싶습니다. 내가 어떻게이 일을 할 수 있겠 니?

+1

와우, "nginx NTLMv2"에 대한 Google 검색을 수행하는 것은 이미 첫 페이지에 표시되어 있으며, 나는이 질문에 불과 7 분 전에 질문했습니다. –

답변

5

그런 식으로 달성하는 가장 쉬운 방법은 nginx 서버에서 NTLMv2 인증을 시뮬레이트하고 요청을 프록시로 리디렉션하고 응답을 확인하는 것입니다. 설치를 재현 할 수 없으므로 아래 코드는 테스트되지는 않았지만 작동해야합니다. 그렇지 않으면 약간의 도움이됩니다. 내가 당신을 도움이되기를 바랍니다 http://davenport.sourceforge.net/ntlm.html

:

<?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 프로토콜의 기준을 사용했다. 의견을 말씀해주십시오.

+0

도움을 주셔서 감사합니다. 나중에 코드를 사용해 보겠습니다. –

+0

타입 -1 블록 내에서'$ response'는 결코 어디에도 설정되지 않지만 사용됩니다. 그래서 나는 curl_setopt ($ ch, CURLOPT_RETURNTRANSFER, 1);을 설정하고 모든'$ response'를'$ result'로 변경했습니다. 그것은 지금까지 잘 작동하지는 않지만 ... –

+0

@MarkTomlin 오, 미안하다. 내 잘못. e_reporting을 E_ALL로 설정하려고 시도 했습니까? 어쩌면 당신은 $ message 나 $ result처럼 당신의 로그에 디버그 내용을 출력하기 위해 syslog() 메소드를 사용할 수 있습니다. – Max