2013-06-25 111 views
2

我實際上正在用Symfony 2構建一個Intranet,並且我必須自動登錄用戶(我的意思是沒有登錄表單...)。目前,我使用的是我的控制器其中更改標題以在瀏覽器上啓動NTLM身份驗證。它運行良好,但在用戶登錄後,他無法發送任何POST表單:所有值都是空的。所有這些問題都在Internet Explorer上,在Firefox和Chrome上都沒問題。爲了使用這種方法,我必須在我的Apache配置中將KeepAlive設置爲On,以使其在Internet Explorer上工作。Symfony 2上的NTLM身份驗證

我使用此代碼,通過NTLM來獲取用戶登錄:

public function getInfos() { 

    $headers = apache_request_headers(); 
    $infos = array(); 

    if (!isset($headers['Authorization'])) { 
     header('HTTP/1.1 401 Unauthorized'); 
     header('WWW-Authenticate: NTLM'); 
     exit; 
    } 

    $auth = $headers['Authorization']; 

    if (substr($auth, 0, 5) == 'NTLM ') { 
     $msg = base64_decode(substr($auth, 5)); 
     if (substr($msg, 0, 8) != "NTLMSSP\x00") 
      die('error header not recognised'); 

     if ($msg[8] == "\x01") { 
      $msg2 = "NTLMSSP\x00\x02\x00\x00\x00" . 
        "\x00\x00\x00\x00" . // target name len/alloc 
        "\x00\x00\x00\x00" . // target name offset 
        "\x01\x02\x81\x00" . // flags 
        "\x00\x00\x00\x00\x00\x00\x00\x00" . // challenge 
        "\x00\x00\x00\x00\x00\x00\x00\x00" . // context 
        "\x00\x00\x00\x00\x00\x00\x00\x00"; // target info len/alloc/offset 

      header('HTTP/1.1 401 Unauthorized'); 
      header('WWW-Authenticate: NTLM ' . trim(base64_encode($msg2))); 
      exit; 
     } else if ($msg[8] == "\x03") { 

      function get_msg_str($msg, $start, $unicode = true) { 
       $len = (ord($msg[$start + 1]) * 256) + ord($msg[$start]); 
       $off = (ord($msg[$start + 5]) * 256) + ord($msg[$start + 4]); 
       if ($unicode) 
        return str_replace("\0", '', substr($msg, $off, $len)); 
       else 
        return substr($msg, $off, $len); 
      } 

      $user = get_msg_str($msg, 36); 
      $domain = get_msg_str($msg, 28); 
      $workstation = get_msg_str($msg, 44); 

      $infos = array('login' => $user, 'domaine' => $domain, 'machine' => $workstation); 
     } 
    } 
    return $infos; 
} 

我找了個其他的方式,但對於那些誰在Symfony的工作:問題是太舊了,所以如果你有一個想法如何解決這個問題或另一種更好,更清潔的方式來與Symfony做到這一點。

+0

你想要基本的HTTP身份驗證彈出?自動登錄用戶意味着什麼?要驗證用戶必須告訴他/她是誰? symfony安全中有很多認證機制(基本http,表單登錄等) – vishal

回答

1

這個包是做你想要的嗎? https://github.com/ecoad/NtlmBundle

它是sf2.0 compilant,所以你可能將不得不更新它最近的sf版本。

+0

那麼。謝謝,因爲我已經降級了我的框架版本並且適應了我的問題。 –

2

不好意思回答這個老問題,但我面臨着同樣的問題,我分享了一些線索以供將來的小夥子:(!)

有關NTLM認證和空POST的IE就是一個功能,以避免網絡不必要的負載:

當頁面上的某個元素需要NTLM握手時,IE假定所有將來的請求(在域範圍內)都需要NTLM認證......爲了保留網絡,IE只發送POST內容在第三輪預期的握手中。 如果您的應用沒有觸發該認證,則不會發送POST內容。

這是詳細解釋(和比我更好的詞)在這裏:http://blogs.msdn.com/b/ieinternals/archive/2010/11/22/internet-explorer-post-bodies-are-zero-bytes-in-length-when-authentication-challenges-are-expected.aspx

爲了解決您的問題,您需要在每次呼叫(或第一次呼叫後的每個後續呼叫)上實施NTLM身份驗證,您可以使用Symfony2在線文檔中起草的海關防火牆/身份驗證提供程序:http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html。由於這不是很容易實現,我建議您使用現有的Bundles來更多地關注代碼,而不是這些痛苦的功能。

+0

好的,謝謝,我找了一段時間回答了這個問題,但最後我用另外一種方式回答了這個問題: - 降級框架以匹配@Paul Andrieux推薦的軟件包版本 - 使用該軟件包對於NTLM身份驗證:) –