Пример PHP-дайджеста HTTP-аутентификации не работает, почему? - PullRequest
10 голосов
/ 03 марта 2011

Поэтому я решил использовать дайджест-аутентификацию HTTP для моего REST API.Я прогуглил это и нашел запись в руководстве по PHP с примером того, как это сделать.Поэтому я копирую скрипт, помещаю его в index.php на моем сервере, открываю страницу в браузере, после ввода моих учетных данных браузер снова запрашивает их, и я зацикливаюсь на бесконечном цикле ввода учетных данных.Сценарий включен ниже и может быть найден здесь .

Пример # 7 Пример аутентификации дайджеста HTTP

<?php
$realm = 'Restricted area';

//user => password
$users = array('admin' => 'mypass', 'guest' => 'guest');


if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
    header('HTTP/1.1 401 Unauthorized');
    header('WWW-Authenticate: Digest realm="'.$realm.
           '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');

    die('Text to send if user hits Cancel button');
}


// analyze the PHP_AUTH_DIGEST variable
if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||
    !isset($users[$data['username']]))
    die('Wrong Credentials!');


// generate the valid response
$A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);

if ($data['response'] != $valid_response)
    die('Wrong Credentials!');

// ok, valid username & password
echo 'Your are logged in as: ' . $data['username'];


// function to parse the http auth header
function http_digest_parse($txt)
{
    // protect against missing data
    $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
    $data = array();
    $keys = implode('|', array_keys($needed_parts));

    preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER);

    foreach ($matches as $m) {
        $data[$m[1]] = $m[3] ? $m[3] : $m[4];
        unset($needed_parts[$m[1]]);
    }

    return $needed_parts ? false : $data;
}
?>

Я также пробовал базовую аутентификациюи это сработало отлично.

Пример # 6 Пример базовой HTTP-аутентификации

<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
    header('WWW-Authenticate: Basic realm="My Realm"');
    header('HTTP/1.0 401 Unauthorized');
    echo 'Text to send if user hits Cancel button';
    exit;
} else {
    echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
    echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";
}
?>

Кажется, что $_SERVER['PHP_AUTH_DIGEST'] всегда пуст.

Что-то не так с сценарием или мое окружение напугано, и если да, то как мне это исправить?

РЕДАКТИРОВАТЬ: В сценарии нет ничего плохого.Вина лежит на сервере.Если кто-нибудь знает, что может вызвать это, пожалуйста, дайте мне знать.

Ответы [ 2 ]

5 голосов
/ 20 апреля 2011

Дайджест-аутентификация - это отдельный модуль Apache, который часто не устанавливается на серверах, особенно в дешевых хостинговых компаниях.Его нужно включить, чтобы использовать его.

http://httpd.apache.org/docs/current/mod/mod_auth_digest.html

Зависит от вашего дистрибутива, как установить его, если вы используете Linux.На моем Ubuntu Linux было достаточно создать символическую ссылку модуля из папки деактивированных модулей на активированные модули одним запуском sudo a2enmod auth_digest на оболочке.Это и перезапуск Apache, конечно.

Я не знаю о Windows.

1 голос
/ 04 апреля 2011

У вас есть mod_headers , загруженные в Apache (я полагаю, ваш сервер работает под Apache)?

Вы можете выяснить это с помощью следующей командной строки (для выполнения которой могут потребоваться привилегии):

httpd -M | grep head
...