5

スクリプトの実行にphp-fpmを使用するnginx Webサーバーがあり、サーバーを閲覧しているクライアントのNTLMv2資格情報を取得したいと考えています。ユーザーを認証するために、ローカル ネットワーク内にプロキシ サーバーがあります。問題は、nginx サーバーを認証させる方法、または PHP が NTLMv2 を使用してユーザーの資格情報を取得し、情報を返す方法です。クライアントがシステム内で正しい資格情報を取得できるようにするには、少なくともユーザー名を知る必要があることは明らかです。

たとえば /login.php にアクセスするときに、クライアントに関する情報をサーバーに戻す限り、プロキシサーバーへのアップストリーム接続を作成しても問題ありません。タイプ 3 メッセージ。この情報をセッション内に保存し、その時点から使用できます。


ローカル エリア ネットワーク内で nginx、PHP、および SQLite を実行している Linux サーバーがあります。このサーバーに接続しているコンピューターはすべて、ネットワークへの Windows ログインを使用する Windows ベースです。ログインは NTLMv2 認証を使用し、外部 Web への接続を確立するためにすべてのクライアントが通過する必要があるプロキシ経由でネットワーク外部の Web サイトにアクセスします。私がやりたいことは、LAN Web サーバーへのログインに NTLMv2 認証情報を使用することです。これを行う方法について何か提案はありますか?

4

1 に答える 1

5

そのようなことを達成する最も簡単な方法は、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)
                }
            }
        }
    }
}?>

NTLM プロトコルのこのリファレンスを使用しました: http://davenport.sourceforge.net/ntlm.html

お役に立てば幸いです。お気軽にコメントください。

于 2013-08-19T17:39:58.637 に答える