mirror of
https://github.com/php/doc-es.git
synced 2026-03-26 00:12:06 +01:00
git-svn-id: https://svn.php.net/repository/phpdoc/es/trunk@337996 c90b9560-bf6c-de11-be94-00142212c4b1
258 lines
9.4 KiB
XML
258 lines
9.4 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!-- $Revision$ -->
|
|
<!-- EN-Revision: 744111cf061120a5e82033a50ca0031902e102d4 Maintainer: seros Status: ready -->
|
|
<!-- Reviewed: yes Maintainer: seros -->
|
|
<chapter xml:id="features.http-auth" xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink">
|
|
<title>Autenticación HTTP con PHP</title>
|
|
|
|
<simpara>
|
|
Con la
|
|
función <function>header</function> se puede enviar un mensaje de <literal>"Autenticación requerida"</literal>
|
|
al navegador del cliente para mostrar una ventana emergente donde introducir un
|
|
usuario y una contraseña. Una vez introducidos estos datos,
|
|
el URL que contiene el script de PHP será invocado de nuevo con las
|
|
<link linkend="reserved.variables">variables predefinidas</link>
|
|
<varname>PHP_AUTH_USER</varname>, <varname>PHP_AUTH_PW</varname>
|
|
y <varname>AUTH_TYPE</varname> establecidas al nombre de usuario, contraseña y
|
|
tipo de autenticación, respectivamente. Estas variables se encuentran en
|
|
el array <varname>$_SERVER</varname>. Se admiten ambos métodos de autenticación,
|
|
'Basic' y 'Digest' (desde PHP 5.1.0). Véase la
|
|
función <function>header</function> para más información.
|
|
</simpara>
|
|
|
|
<para>
|
|
Un fragmento de un script de ejemplo que forzaría la autenticación
|
|
en una página es el siguiente:
|
|
</para>
|
|
<para>
|
|
<example>
|
|
<title>Ejemplo de autenticación HTTP 'Basic'</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
if (!isset($_SERVER['PHP_AUTH_USER'])) {
|
|
header('WWW-Authenticate: Basic realm="Mi dominio"');
|
|
header('HTTP/1.0 401 Unauthorized');
|
|
echo 'Texto a enviar si el usuario pulsa el botón Cancelar';
|
|
exit;
|
|
} else {
|
|
echo "<p>Hola {$_SERVER['PHP_AUTH_USER']}.</p>";
|
|
echo "<p>Introdujo {$_SERVER['PHP_AUTH_PW']} como su contraseña.</p>";
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<para>
|
|
<example>
|
|
<title>Ejemplo de autenticación HTTP 'Digest'</title>
|
|
<para>
|
|
Este ejemplo muestra cómo implementar un sencillo script de
|
|
autenticación HTTP 'Digest'. Para más información lea el <link
|
|
xlink:href="&url.rfc;2617">RFC 2617</link>.
|
|
</para>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
$dominio = 'Area restringida';
|
|
|
|
// usuario => contraseña
|
|
$usuarios = array('admin' => 'micontraseña', 'invitado' => 'invitado');
|
|
|
|
|
|
if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
|
|
header('HTTP/1.1 401 Unauthorized');
|
|
header('WWW-Authenticate: Digest realm="'.$dominio.
|
|
'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($dominio).'"');
|
|
|
|
die('Texto a enviar si el usuario pulsa el botón Cancelar');
|
|
}
|
|
|
|
|
|
// Analizar la variable PHP_AUTH_DIGEST
|
|
if (!($datos = analizar_http_digest($_SERVER['PHP_AUTH_DIGEST'])) ||
|
|
!isset($usuarios[$datos['username']]))
|
|
die('Credenciales incorrectas');
|
|
|
|
|
|
// Generar una respuesta válida
|
|
$A1 = md5($datos['username'] . ':' . $dominio . ':' . $usuarios[$datos['username']]);
|
|
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$datos['uri']);
|
|
$respuesta_válida = md5($A1.':'.$datos['nonce'].':'.$datos['nc'].':'.$datos['cnonce'].':'.$datos['qop'].':'.$A2);
|
|
|
|
if ($datos['response'] != $respuesta_válida)
|
|
die('Credenciales incorrectas');
|
|
|
|
// Todo bien, usuario y contraseña válidos
|
|
echo 'Se ha identificado como: ' . $datos['username'];
|
|
|
|
|
|
// Función para analizar la cabecera de autenticación HTTP
|
|
function analizar_http_digest($txt)
|
|
{
|
|
// Protección contra datos ausentes
|
|
$partes_necesarias = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
|
|
$datos = array();
|
|
$claves = implode('|', array_keys($partes_necesarias));
|
|
|
|
preg_match_all('@(' . $claves . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $coincidencias, PREG_SET_ORDER);
|
|
|
|
foreach ($coincidencias as $c) {
|
|
$datos[$c[1]] = $c[3] ? $c[3] : $c[4];
|
|
unset($partes_necesarias[$c[1]]);
|
|
}
|
|
|
|
return $partes_necesarias ? false : $datos;
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
|
|
<note>
|
|
<title>Sobre la compatibilidad</title>
|
|
<para>
|
|
Hay que tener cuidado al codificar las líneas de cabeceras HTTP. Para garantizar la mayor
|
|
compatibilidad con todos los clientes, la palabra 'Basic' debe escribirse con
|
|
'B' mayúscula, la cadena del dominio debe estar entre comillas dobles (no simples),
|
|
y debería haber exactamente un espacio precediendo al código <emphasis>401</emphasis> de la
|
|
línea de la cabecera <emphasis>HTTP/1.0 401</emphasis>. Los parámetros de autenticación deben
|
|
estar separados por comas, como se vió en el ejemplo de 'Digest' anterior.
|
|
</para>
|
|
</note>
|
|
|
|
<para>
|
|
En lugar de imprimir simplemente <varname>PHP_AUTH_USER</varname>
|
|
y <varname>PHP_AUTH_PW</varname> como se hizo en el ejemplo anterior,
|
|
podría ser conveniente validar el usuario y la contraseña,
|
|
tal vez enviando una consulta a una base de datos o buscando el
|
|
usuario en un fichero dbm.
|
|
</para>
|
|
|
|
<para>
|
|
Cuidado con los navegadores Internet Explorer defectuosos. Parecen
|
|
ser muy quisquillosos con el orden de las cabeceras. Por ahora,
|
|
parece ser que el truco está en enviar la cabecera
|
|
<emphasis>WWW-Authenticate</emphasis> antes que la cabecera
|
|
<literal>HTTP/1.0 401</literal>.
|
|
</para>
|
|
|
|
<simpara>
|
|
Para prevenir que alguien escriba un script que
|
|
revele la contraseña de una página que se autenticó con un
|
|
mecanismo externo tradicional, las variables PHP_AUTH no se
|
|
establecerán si la autenticación externa está habilitada para esa
|
|
página en particular y si el &safemode; está habilitado. Independientemente,
|
|
se puede emplear <varname>REMOTE_USER</varname>
|
|
para identificar al usuario autenticado externamente. De este modo, se podrá usar
|
|
<varname>$_SERVER['REMOTE_USER']</varname>.
|
|
</simpara>
|
|
|
|
<note>
|
|
<title>Sobre la configuración</title>
|
|
<para>
|
|
PHP utiliza la presencia de una directiva <literal>AuthType</literal> para
|
|
determinar si una autenticación externa está en uso.
|
|
</para>
|
|
</note>
|
|
|
|
<simpara>
|
|
Observe, sin embargo, que lo anterior no impide que alguien que
|
|
controle un URL no autenticado pueda robar contraseñas
|
|
de URL autenticados en el mismo servidor.
|
|
</simpara>
|
|
<simpara>
|
|
Tanto Netscape Navigator como Internet Explorer borran la caché de autenticación
|
|
de la ventana del navegador local para el dominio al recibr una respuesta
|
|
401 del servidor. Esto, en efecto, puede hacer que se cierre la sesión de un usuario,
|
|
obligándolo a reintroducir su nombre de usuario y contraseña. Algunos utilizan esto para
|
|
inicios de sesión «expiradas» o proveer un botón de «Cerrar sesión».
|
|
</simpara>
|
|
<para>
|
|
<example>
|
|
<title>Ejemplo de autenticación HTTP forzando un nuevo usuario/contraseña</title>
|
|
<programlisting role="php">
|
|
<![CDATA[
|
|
<?php
|
|
function autenticar() {
|
|
header('WWW-Authenticate: Basic realm="Sistema de autenticación de prueba"');
|
|
header('HTTP/1.0 401 Unauthorized');
|
|
echo "Debe introducir un ID y contraseña de identificación válidos para acceder a este recurso\n";
|
|
exit;
|
|
}
|
|
|
|
if (!isset($_SERVER['PHP_AUTH_USER']) ||
|
|
($_POST['VistoAntes'] == 1 && $_POST['UsuarioAntiguo'] == $_SERVER['PHP_AUTH_USER'])) {
|
|
autenticar();
|
|
} else {
|
|
echo "<p>Bienvenido: " . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "<br />";
|
|
echo "Antiguo: " . htmlspecialchars($_REQUEST['UsuarioAntiguo']);
|
|
echo "<form action='' method='post'>\n";
|
|
echo "<input type='hidden' name='VistoAntes' value='1' />\n";
|
|
echo "<input type='hidden' name='UsuarioAntiguo' value=\"" . htmlspecialchars($_SERVER['PHP_AUTH_USER']) . "\" />\n";
|
|
echo "<input type='submit' value='Reautenticar' />\n";
|
|
echo "</form></p>\n";
|
|
}
|
|
?>
|
|
]]>
|
|
</programlisting>
|
|
</example>
|
|
</para>
|
|
<simpara>
|
|
El estándar de autenticación <literal>HTTP Basic</literal> no requiere
|
|
este funcionamiento, por lo que no se debería depender de ello. Las pruebas con
|
|
<literal>Lynx</literal> han mostrado que <literal>Lynx</literal> no limpia
|
|
las credenciales de autenticación con una respuesta 401 del servidor, por lo que al presionar «atrás»
|
|
y luego «adelante» abrirá el recurso nuevamente mientras los requisitos de credenciales
|
|
no hayan cambiado. Sin embargo, el usuario puede pulsar la
|
|
tecla <literal>'_'</literal> para limpiar su información de autenticación.
|
|
</simpara>
|
|
<simpara>
|
|
Para que la Autenticación HTTP funcione en un servidor IIS con la versión CGI
|
|
de PHP, se debe editar la configuracion de "<literal>Seguridad de directorios</literal>" de IIS:
|
|
hacer clic en "<literal>Editar</literal>" y solo marcar
|
|
"<literal>Acceso anónimo</literal>"; todos los demas campos
|
|
deberían estar sin marcar.
|
|
</simpara>
|
|
<note>
|
|
<title>Sobre IIS:</title>
|
|
<simpara>
|
|
Para que funcione la Autenticación HTTP con IIS, la directiva de PHP
|
|
<link linkend="ini.cgi.rfc2616-headers">cgi.rfc2616_headers</link> debe
|
|
establecerse a <literal>0</literal> (el valor predeterminado).
|
|
</simpara>
|
|
</note>
|
|
<note>
|
|
<para>
|
|
Si el <link linkend="ini.safe-mode">modo seguro</link> está habilitado, el
|
|
uid del script se añade a la parte del <literal>dominio</literal> de la
|
|
cabecera <literal>WWW-Authenticate</literal>.
|
|
</para>
|
|
</note>
|
|
|
|
</chapter>
|
|
|
|
<!-- Keep this comment at the end of the file
|
|
Local variables:
|
|
mode: sgml
|
|
sgml-omittag:t
|
|
sgml-shorttag:t
|
|
sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t
|
|
sgml-indent-step:1
|
|
sgml-indent-data:t
|
|
indent-tabs-mode:nil
|
|
sgml-parent-document:nil
|
|
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
|
|
sgml-exposed-tags:nil
|
|
sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil
|
|
End:
|
|
vim600: syn=xml fen fdm=syntax fdl=2 si
|
|
vim: et tw=78 syn=sgml
|
|
vi: ts=1 sw=1
|
|
-->
|