cvs: phpdoc-ca /features http-auth.xml
| From: | Eduard Capell Brufau | Date: | Sun, 28 Aug 2005 16:57:42 +0000 |
| Subject: | cvs: phpdoc-ca /features http-auth.xml | ||
| Groups: | php.doc.ca | ||
| Request: | Send a blank email to doc-ca+get-59@lists.php.net to get a copy of this message | ||
eduardcapell Sun Aug 28 12:57:42 2005 EDT
Added files:
/phpdoc-ca/features http-auth.xml
Log:
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 -->
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 -->