2013-06-25 5 views
2

Я фактически создаю интранет с Symfony 2, и мне приходится регистрировать автоматически пользователей (я имею в виду не регистрационную форму ...) .. На данный момент я использую метод с моего контроллера которые изменяют заголовки для запуска проверки подлинности NTLM в браузере. Он работает хорошо, но после того, как пользователь вошел в систему, он не может отправить форму POST: все значения пустые. Все эти проблемы в Internet Explorer, на Firefox и Chrome - все в порядке. Для использования этого метода мне пришлось установить KeepAlive в On в моей конфигурации Apache, чтобы он работал в Internet Explorer.NTLM Authentication on Symfony 2

Я использую этот код, чтобы получить логин пользователя с помощью 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 компилятор, поэтому вам, возможно, придется обновить его для последней версии sf.

+0

Ну. Спасибо, так как я понизил мою версию фреймворка и адаптирую его для своей проблемы. –

2

К сожалению ответить на этот старый вопрос, но, как я столкнулся с таким же вопросом, я делю некоторые подсказки для будущих хлопцев: (!)

IE вещь NTLM аутентификации и пустого POST это функция, чтобы избежать сетевая ненужная нагрузка:

Если какой-либо элемент на странице нуждается в квитировании 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 на каждом вызове (или после каждого последующего вызова после первого запуска), вы можете сделать это с помощью таможенных брандмауэров/поставщиков Authent, как указано в онлайн-документе Symfony2 : http://symfony.com/doc/current/cookbook/security/custom_authentication_provider.html.

Поскольку это не очень просто реализовать, я порекомендую вам использовать существующие пакеты, чтобы больше сосредоточиться на вашем коде, чем на темах больных функций.

+0

Ну, спасибо, я искал такой ответ на некоторое время, но, наконец, я сделал это другим способом: - Снижение рамки в соответствии с версией, требуемой для пакета, рекомендованной @Paul Andrieux - Используйте этот комплект для аутентификации NTLM :) –