array ( 0 => 'index.php', 1 => 'PHP Manual', ), 'head' => array ( 0 => 'UTF-8', 1 => 'pt_BR', ), 'this' => array ( 0 => 'features.http-auth.php', 1 => 'Autenticação HTTP com PHP', ), 'up' => array ( 0 => 'features.php', 1 => 'Características', ), 'prev' => array ( 0 => 'features.php', 1 => 'Características', ), 'next' => array ( 0 => 'features.cookies.php', 1 => 'Cookies', ), 'alternatives' => array ( ), 'source' => array ( 'lang' => 'pt_BR', 'path' => 'features/http-auth.xml', ), ); $setup["toc"] = $TOC; $setup["toc_deprecated"] = $TOC_DEPRECATED; $setup["parents"] = $PARENTS; manual_setup($setup); ?>
Pode-se utilizar a função
header() para enviar uma mensagem de "Authentication Required"
para o browser cliente, causando o aparecimento de uma janela para a entrada de Nome de Usuário/Senha.
Uma vez que o usuário preencha um nome de usuário e uma senha,
a URL contendo o script PHP será chamada mais uma vez com as
variáveis predefinidas
PHP_AUTH_USER, PHP_AUTH_PW,
e AUTH_TYPE para determinar o nome de usuário, senha e
tipo da autenticação, respectivamente. Estas variáveis predefinidas são encontradas
nos arrays $_SERVER. Somente os métodos de autenticação "Basic" e "Digest"
(a partir do PHP 5.1.0) são suportados. Consulte a função
header() para mais informações.
Um exemplo de fragmento de script que forçaria a autenticação do cliente em uma página:
Exemplo #1 Exemplo de Autenticação HTTP "Basic"
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="My Realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'Texto enviado caso o usuário clique no botão Cancelar';
exit;
} else {
echo "<p>Olá, {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>Você digitou {$_SERVER['PHP_AUTH_PW']} como sua senha.</p>";
}
?>
Exemplo #2 Exemplo de autenticação HTTP "Digest"
Este exemplo demonstra como implementar um script simples de autenticação HTTP "Digest". Para mais informações, leia o » RFC 2617.
<?php
$realm = 'Área restrita';
//usuário => senha
$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('Texto enviado caso o usuário clique no botão Cancelar');
}
// analisar a variável PHP_AUTH_DIGEST
if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) ||
!isset($users[$data['username']]))
die('Credenciais inválidas!');
// gerar a resposta válida
$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('Credenciais inválidas!');
// ok, nome de usuário e senha válidos
echo 'Você está logado como: ' . $data['username'];
// função para decompor o http auth header
function http_digest_parse($txt)
{
// proteção contra dados incompletos
$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;
}
?>
Nota: Nota sobre compatibilidade
Por favor, seja cauteloso ao codificar as linhas do cabeçalho HTTP. Para garantir máxima compatibilidade com todos os clientes, a palavra-chave "Basic" deve ser escrita com um "B" maiúsculo, a string realm deve ser envolvida por aspas duplas (nunca por aspas simples), e apenas um espaço deve preceder o código 401 na linha do cabeçalho HTTP/1.0 401. Parâmetros de autenticação precisam ser separados por vírgula, como visto no exemplo acima de digest.
Ao invés de simplesmente exibir PHP_AUTH_USER e PHP_AUTH_PW, como no exemplo acima, talvez queira verificar a validade do nome de usuário e senha. Talvez enviando uma consulta a um banco de dados, ou procurando o usuário em um arquivo dbm.
Cuidado com browsers Internet Explorer bugados por aí. Eles
parecem muito minuciosos sobre a ordem dos cabeçalhos. Enviar
o cabeçalho WWW-Authenticate antes do
cabeçalho HTTP/1.0 401
parece resolver isso
por enquanto.
Nota: Nota de configuração
PHP usa uma diretiva chamada
AuthType
para determinar se a autenticação externa está em efeito.
Perceba, entretanto, que a diretiva citada acima não previne que alguém que controle uma URL não autenticada roube senhas de URLs autenticadas no mesmo servidor.
Tanto o Netscape Navigator quanto o Internet Explorer apagarão o cache de autenticação da janela local do browser para o realm após receber uma resposta 401 do servidor. Isso pode efetivamente "deslogar" um usuário, forçando o mesmo a re-entrar seu nome de usuário e senha. Algumas pessoas usam isso para delimitar o tempo de um login, ou prover um botão de "log-out".
Exemplo #3 Exemplo de Autenticação HTTP forçando um novo nome/senha
<?php
function authenticate() {
header('WWW-Authenticate: Basic realm="Test Authentication System"');
header('HTTP/1.0 401 Unauthorized');
echo "Você deve digitar um login e senha válidos para acessar este recurso\n";
exit;
}
if (!isset($_SERVER['PHP_AUTH_USER']) ||
($_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) {
authenticate();
} else {
echo "<p>Bem-vindo: " . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "<br />";
echo "Antigo: " . htmlspecialchars($_REQUEST['OldAuth']);
echo "<form action='' method='post'>\n";
echo "<input type='hidden' name='SeenBefore' value='1' />\n";
echo "<input type='hidden' name='OldAuth' value=\"" . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "\" />\n";
echo "<input type='submit' value='Re-autenticar' />\n";
echo "</form></p>\n";
}
?>
Este comportamento não é requerido pelo padrão de autenticação HTTP Basic
,
então nunca se deve depender dele. Testes com
Lynx
tem mostrado que Lynx
não apaga
as credenciais de autenticação com uma resposta 401 do servidor, assim, ao pressionar "Voltar"
e então "Ir" novamente abrirá o recurso contanto que os requerimento de credenciais
não tenha mudado. Contudo, o usuário pode pressionar a tecla
'_'
para apagar suas informações de autenticação.
Para fazer com que a autenticação HTTP funcione utilizando um servidor IIS com a versão CGI
do PHP é necessário editar a configuração "Directory Security
" do IIS.
Clique em "Edit
" e marque somente
"Anonymous Access
",
deixe todos os outros campos desmarcados.
Nota: Nota sobre IIS:
Para que a autenticação HTTP funcione com IIS, a diretiva do PHP cgi.rfc2616_headers deve ser definida como0
(o valor default).