簡體   English   中英

使用cURL在不同主機上對當前用戶進行PHP NTLM身份驗證失敗

[英]PHP NTLM authentication of current user on different host fails using cURL

我在本地網絡中的一台服務器上使用PHP 7.1.7和cURL 7.54.1,並且由於開發要求,我必須能夠訪問存儲在另一台本地網絡服務器上的文件(PHP 4.3或類似的文件) )。 由於我系統中其他某些組件的版本要求,我必須將腳本保留在較新的服務器上,並將其訪問的文件保存在較舊的服務器上。 我使用以下設置將當前NTLM用戶憑據從該腳本所在的源服務器傳遞到目標服務器-應該可以運行,但不成功:

function file_get_contents_curl($url) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
    curl_setopt($curl, CURLOPT_UNRESTRICTED_AUTH, TRUE);
    curl_setopt($curl, CURLOPT_USERPWD, ":");
    $data = curl_exec($curl);
    curl_close($curl);
    return $data;
}

header("Pragma: public");
header("Expires: -1");
header("Cache-Control: public, must-revalidate, post-check=0, pre-check=0");    
header('Content-Type: '.get_mime_type($fileresult['filename']));
header('Content-Disposition: attachment; filename="'.$fileresult['originalname'].'"');
$contents = file_get_contents_curl($path);
$localSize = strlen($contents);
header('Content-Length: ' . $localSize);
echo $contents;
ob_flush();
flush();
exit();

當我明確指定我的

curl_setopt($ curl,CURLOPT_USERPWD,“ [用戶名]:[密碼]”);

,它可以完美地運行,但是當嘗試重用現有的用戶憑據時會失敗。 作為管理員,我不想將我的憑據以純文本形式保留在代碼中-這是公然的安全違規行為,並且創建對這些文件具有訪問權限的虛擬用戶個人資料會阻止在舊服務器上正確記錄實際的用戶活動-這本身就是安全問題。

我發現此bug報告https://bugs.php.net/bug.php?id=62195涉及同一問題,但它與完全不同的PHP版本(5.4.3)有關,我確實考慮了開發人員的評論-仍然沒有用。

有沒有我忘記正確設置的curl_setopt設置才能起作用? 也許IIS服務器可能需要進行某些配置更改,以允許PHP在cURL請求中重新使用這些憑據? 還是應該按目前的方式工作,而我的下一步就是向php.net提交錯誤報告?

感謝您的幫助!


編輯:

無論我使用上面的代碼請求了哪個文件(帶有繼承的用戶名和密碼),該腳本都會返回一個1.3k文件,並帶有預期的文件名和擴展名(.PDF,.PNG或任何其他文件),但包含的內容完全如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>401 - Unauthorized: Access is denied due to invalid credentials.</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;}
fieldset{padding:0 15px 10px 15px;} 
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;} 
h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} 
#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF;
background-color:#555555;}
#content{margin:0 0 0 2%;position:relative;}
.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
-->
</style>
</head>
<body>
<div id="header"><h1>Server Error</h1></div>
<div id="content">
 <div class="content-container"><fieldset>
  <h2>401 - Unauthorized: Access is denied due to invalid credentials.</h2>
  <h3>You do not have permission to view this directory or page using the credentials that you supplied.</h3>
 </fieldset></div>
</div>
</body>
</html>

cURL不返回錯誤-根據它,一切都很好。 當我明確指定用戶名和密碼時,所有返回的文件都有其自己預期的唯一大小和內容。

它應該可以工作,但不知何故

不,如注釋中所述,它不應​​該適用於其他服務器。

為了避免進行兩次身份驗證(這可能難以實現,並且對於最終用戶而言不理想),我有以下想法。

也許您可以僅依靠第二台服務器(PHP 4)上的身份驗證,第一台服務器(PHP 7)未配置為詢問憑據,而是將NTLM消息轉發到第二台服務器,然后在知道第二台服務器時啟動會話(cookie)用戶終於成功進行了身份驗證。 副作用是,所有新會話都將通過將請求轉發到第二台服務器來開始。 也許您可以用PHP來完成所有這些工作,但是我沒有親自嘗試,不幸的是,這花費了太多時間。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM