cvs: phpdoc-ca /features http-auth.xml
[email protected] ("Eduard Capell Brufau") Sun, 28 Aug 2005 16:57:42 -0000
| Newsgroups | php.doc.ca |
|---|---|
| Message-ID | <cvseduardcapell1125248262@cvsserver> |
--eduardcapell1125248262
Content-Type: text/plain
eduardcapell Sun Aug 28 12:57:42 2005 EDT
Added files:
/phpdoc-ca/features http-auth.xml
Log:
--eduardcapell1125248262
Content-Type: text/plain
Content-Disposition: attachment; filename="eduardcapell-20050828125742.txt"
http://cvs.php.net/co.php/phpdoc-ca/features/http-auth.xml?r=1.1&p=1
Index: phpdoc-ca/features/http-auth.xml
+++ phpdoc-ca/features/http-auth.xml
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- $Revision: 1.1 $ -->
<!-- EN-Revision: 1.42 Maintainer: eduardcapell Status: ready -->
<chapter id="features.http-auth">
<title>Autenticació HTTP amb PHP</title>
<simpara>
Els serveis d'Autenticació <acronym>HTTP</acronym> en PHP només estan
disponibles quan executem el PHP com un mòdul d'Apache, i, per tant, no està
disponible en la versió CGI. En un script de PHP (executant-se com a mòdul
d'Apache), és possible d'utilitzar la funció <function>header</function> per
tal d'enviar un missatge "Autenticació Requerida" al navegador del client,
fent que aparegui una finestra d'entrada d'Usuari/Contrassenya. Quan l'usuari
ha introduït l'usuari i la contrassenya, es cridarà la URL que contè l'script
PHP amb les <link linkend="reserved.variables">variables predefinides</link>
<varname>PHP_AUTH_USER</varname>, <varname>PHP_AUTH_PW</varname>,
i <varname>AUTH_TYPE</varname>, establertes amb els valors de l'usuari, la
contrassenya, i el tipus d'autenticació, respectivament. Aquestes variables
predefinides les podem trobar als vectors
<link linkend="reserved.variables.server">$_SERVER</link> i
<varname>$HTTP_SERVER_VARS</varname>. Se suporten els mètodes "Basic" i
"Digest" (des de PHP 5.1.0). Vegeu la funció <function>header</function>
per a saber-ne més.
</simpara>
<note>
<title>Nota de la versió de PHP</title>
<para>
<link linkend="language.variables.superglobals">Autoglobals</link>,
com ara <link linkend="reserved.variables.server">$_SERVER</link>, van
començar a estar disponibles en PHP
<ulink url="&url.php.release4.1.0;">4.1.0</ulink>.
<varname>$HTTP_SERVER_VARS</varname> ha estat disponible des de PHP 3.
</para>
</note>
<para>
Un exemple de fragment de codi que forçaria el client a autenticar-se en una
pàgina seria de la manera següent:
</para>
<para>
<example>
<title>Exemple d'Autenticació HTTP Bàsica</title>
<programlisting role="php">
<![CDATA[
<?php
if (!isset($_SERVER['PHP_AUTH_USER'])) {
header('WWW-Authenticate: Basic realm="El Meu Realm"');
header('HTTP/1.0 401 Unauthorized');
echo 'Text a enviar si usuari prem el botó Cancel·lar';
exit;
} else {
echo "<p>Hola {$_SERVER['PHP_AUTH_USER']}.</p>";
echo "<p>Heu entrat {$_SERVER['PHP_AUTH_PW']} en la contrassenya.</p>";
}
?>
]]>
</programlisting>
</example>
</para>
<para>
<example>
<title>Exemple d'Autenticació HTTP Digest</title>
<para>
Aquest exemple us mostra com s'implementaria una seqüència amb Autenticació
HTTP Digest. Per més informació, llegiu-vos la
<ulink url="&url.rfc;2617">RFC 2617</ulink>.
</para>
<programlisting role="php">
<![CDATA[
<?php
$realm = 'Àrea restringida';
//user => password
$users = array('admin' => 'el_meu_pass', 'guest' => 'guest');
if (!isset($_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 a enviar si usuari prem botó Cancel·lar');
}
// analitzem la variable PHP_AUTH_DIGEST
preg_match('/username="(?P<username>.*)",\s*realm="(?P<realm>.*)",\s*nonce="(?P<nonce>.*)",\s*uri="(?P<uri>.*)",\s*response="(?P<response>.*)",\s*opaque="(?P<opaque>.*)",\s*qop=(?P<qop>.*),\s*nc=(?P<nc>.*),\s*cnonce="(?P<cnonce>.*)"/', $_SERVER['PHP_AUTH_DIGEST'], $digest);
if (!isset($users[$digest['username']]))
die('Nom d\'usuari no vàlid!');
// generem la resposta vàlida
$A1 = md5($digest['username'] . ':' . $realm . ':' . $users[$digest['username']]);
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$digest['uri']);
$valid_response = md5($A1.':'.$digest['nonce'].':'.$digest['nc'].':'.$digest['cnonce'].':'.$digest['qop'].':'.$A2);
if ($digest['response'] != $valid_response)
die('Credencials Incorrectes!');
// ok, usuari & contrassenya correctes
echo 'Us heu identificat com a: ' . $digest['username'];
?>
]]>
</programlisting>
</example>
</para>
<note>
<title>Nota de Compatibilitat</title>
<para>
Aneu amb molt de compte quan escriviu les línies de les capçaleres HTTP. Per
tal de garantir la màxima compatibilitat amb tots els clients, la paraula
clau "Basic" s'ha d'escriure amb una "B" (en majúscula), la cadena de text
del "realm" ha d'estar entre cometes dobles (NO simples), i el codi
<emphasis>401</emphasis> ha d'anar precedit d'exactament un espai en la
línia de la capçalera <emphasis>HTTP/1.0 401</emphasis>.
</para>
</note>
<para>
Enlloc d'escriure els valors de <varname>PHP_AUTH_USER</varname>
i <varname>PHP_AUTH_PW</varname>, tal com s'ha fet en l'exemple previ, potser
voldreu comprovar l'usuari i password per veure si són correctes.
Probablement enviant una consulta a una base de dades, o buscant l'usuari en
un fitxer dbm.
</para>
<para>
Aneu amb compte amb navegadors Internet Explorers "defectuosos". Algunes
versions són molt sensibles a l'ordre de les capçaleres. Per ara, sembla que
si s'envia la capçalera <emphasis>WWW-Authenticate</emphasis> abans de la
capçalera <literal>HTTP/1.0 401</literal> tot funciona correctament.
</para>
<simpara>
Des de PHP 4.3.0, per tal de prevenir que algú escrigui una seqüència que
reveli la contrassenya d'una pàgina que ha estat autenticada a través d'un
mecanisme extern tradicional, les variables PHP_AUTH no estaran establertes
si l'autenticació externa s'ha habilitat per aquella pàgina i &safemode; està
habilitat. En qualsevol cas, es pot utiltizar <varname>REMOTE_USER</varname>
per a identificar l'usuari autenticat externament, utilitzant
<varname>$_SERVER['REMOTE_USER']</varname>.
</simpara>
<note>
<title>Nota de Configuració</title>
<para>
PHP utilitza la presència d'una directiva <literal>AuthType</literal> per a
determinar si l'autenticació externa està habilitada o no.
</para>
</note>
<simpara>
Observeu, però, que el que s'ha comentat anteriorment no evita que algú que
controla una URL no autenticada pugui robar contrassenyes d'URLs autenticades
en el mateix servidor.
</simpara>
<simpara>
Tant el Netscape Navigator com l'Internet Explorer esborren la memòria cau
d'autenticació del navegador local pel reialme, després de rebre una resposta
401 des del servidor. Això força un "log-out" de l'usuari, obligant-lo a
reintroduir el seu nom d'usuari i contrassenya. A vegades s'utilitza això per
tal de simular "time-outs" o per proporcionar botons de "log-out".
</simpara>
<para>
<example>
<title>Exemple d'Autenticació HTTP forçant un nou
usuari/contrassenya</title>
<programlisting role="php">
<![CDATA[
<?php
function authenticate() {
header('WWW-Authenticate: Basic realm="Sistema de Prova d\'Autenticació"');
header('HTTP/1.0 401 Unauthorized');
echo "Heu d\'entrar un nom d\'usuari i contrassenya vàlids per a accedir\n";
exit;
}
if (!isset($_SERVER['PHP_AUTH_USER']) ||
($_POST['SeenBefore'] == 1 && $_POST['OldAuth'] == $_SERVER['PHP_AUTH_USER'])) {
authenticate();
}
else {
echo "<p>Benvingut: {$_SERVER['PHP_AUTH_USER']}<br />";
echo "Antic: {$_REQUEST['OldAuth']}";
echo "<form action='{$_SERVER['PHP_SELF']}' METHOD='post'>\n";
echo "<input type='hidden' name='SeenBefore' value='1' />\n";
echo "<input type='hidden' name='OldAuth' value='{$_SERVER['PHP_AUTH_USER']}' />\n";
echo "<input type='submit' value='Re-Autenticar' />\n";
echo "</form></p>\n";
}
?>
]]>
</programlisting>
</example>
</para>
<simpara>
Aquest comportament no el requereix l'estandard de l'autenticació Bàsica
HTTP, i per tant no us n'heu de refiar. Hem fet proves amb el Lynx, i aquest
no esborra les credencials d'autenticació quan rep una resposta 401, de
manera que anant enrere i endavant amb els botons de navegació, s'obrirà el
recurs protegit, mentre els requeriments de les credencials no hagin canviat.
L'usuari pot, però, prémer la tecla '_' per tal d'esborrar la seva informació
d'autenticació.
</simpara>
<simpara>
Observeu també que fins a PHP 4.3.3, l'Autenticació HTTP no funcionava quan
s'utilitzava el servidor Microsoft IIS amb la versió CGI de PHP, degut a una
limitació de IIS. Per tal de fer que funcioni amb PHP 4.3.3+, heu d'editar la
configuració del IIS, en "Seguretat de Directori". Feu click en "Edició", i
marqueu tan sols "Accés Anònim", i deixeu la resta de camps sense marcar.
</simpara>
<simpara>
Una altra limitació es dóna si esteu utilitzant el mòdul IIS (ISAPI) i PHP 4,
ja que no podreu utilitzar les variables <literal>PHP_AUTH_*</literal>, sinó
que haureu d'utilitzar <literal>HTTP_AUTHORIZATION</literal>. Per exemple,
com en el codi següent: <literal>list($user, $pw) = explode(':',
base64_decode(substr($_SERVER['HTTP_AUTHORIZATION'], 6)));</literal>
</simpara>
<note>
<title>Nota d'IIS:</title>
<simpara>
Per tal que l'Autenticació HTTP funcioni amb IIS, la directiva PHP
<link linkend="ini.cgi.rfc2616-headers">cgi.rfc2616_headers</link> s'ha
d'establir al valor <literal>0</literal> (el seu valor per defecte).
</simpara>
</note>
<note>
<para>
Si està activat el <link linkend="ini.safe-mode">mode segur</link>, l'uid de
l'script s'afegirà al <literal>reialme</literal>, en la part de la capçalera
<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:"../../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
-->
--eduardcapell1125248262--