miércoles, 17 de julio de 2013

Seguridad PHP - Autenticación HTTP básica

La autenticación básica HTTP es un sencillo mecanismo con el que un servidor puede solicitar información de autenticación (un ID de usuario y contraseña) de un cliente. El cliente pasa la información de autenticación al servidor en una cabecera de autorización. Dicha información se encuentra codificada en base-64. Dada su poca seguridad, es útil para sistemas con un número muy limitado de usuarios y donde la protección no es muy importante. Por ejemplo para sistemas donde solo se quiere evitar usuarios anónimos para acceder al algún recurso.

Proceso:

1. El navegador (cliente) iniciará la comunicación realizando la petición al servidor. Y enviará las siguientes cabeceras (similar) al servidor:

 GET /download/report.doc HTTP/1.1   
 Accept: application/msword, */*   
 Accept-Language: en-ES  
 Accept-Encoding: gzip, deflate   
 User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)   
 Host: ejemplo.com  
 Connection: Keep-Alive  

2. Tras recibir la petición del cliente, el servidor comprobará la existencia de los datos de autenticación.
Para ello se necesita poder acceder a los supuestos datos introducidos por el usuario utilizaremos las siguientes constantes:
- $_SERVER['PHP_AUTH_USER']: nombre del usuario .
- $_SERVER['PHP_AUTH_PW']: contraseña del usuario.

En el siguiente ejemplo de código vamos a comprobar la existencia de los datos mediante la función php array_key_exists(); aunque también podríamos usar la función isset().

 public function identificacion() {  
      if ( array_key_exists('PHP_AUTH_USER', $_SERVER) &&  
      array_key_exists(‘PHP_AUTH_PW’, $_SERVER) ) {  
           //...  
      }  
      else{  
           mostrarVentanaLogin();  
      }  
 }  
 function mostrarVentanaLogin() {  
      header('WWW-Authenticate: Basic realm="demo"');  
      header('HTTP/1.0 401 Unauthorized');  
      echo "Usted no tiene permisos.\n";  
      exit;  
 }  

3. Ventana emergente (primera contestación del servidor)

Como en la primera de la comunicación enviada por el cliente no se enviado ninguna información de autenticación, el servidor, mediante la función mostrarVentanaLogin(), enviará las siguientes cabeceras al cliente

 HTTP/1.1 401 Unauthorized  
 Date: Tue, 22 Jun 2010 03:54:06 GMT   
 Server: Apache/2.2.15 (Unix)   
 WWW-Authenticate: Basic realm="demo"   
 ... 


Nota: “Basic realm” es el nombre del servicio al que pretendemos acceder y el mensaje que se mostrará si no podemos acceder a dicho servicio.

La recepción, por parte del navegador, de estas cabeceras provocará que en él se muestre una ventana emergente de autentificación requerida, solicitando usuario y contraseña para poder ingresar a un determinado sitio.

4. Envío de datos de autenticación

En dicha ventana, el usuario introducirá el usuario y la contraseña para identificarse en el sistema.
Dichos datos  se concatenarán  de la siguiente forma usuario:contraseña (símbolo ":" incluido) y serán codificados en base-64. Finalmente se insertará en el campo Authorization.
Posteriormente se procederá a enviar una nueva petición al servidor.

 GET /download/report.doc HTTP/1.1   
 Accept: application/msword, */*   
 Accept-Language: es- ES  
 Accept-Encoding: gzip, deflate   
 User-Agent: Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)   
 Host: ejemplo.com  
 Connection: Keep-Alive   
 Authorization: Basic ZnJhbms6ZmllZGxlcg==  

5. Nuevo procesado por parte del servidor

Con la llegada de una nueva petición al servidor nuevamente buscará los datos de identificación. Para ello internamente decodifica y separa la cadena recibida para extraer el usuario y su contraseña.Y ahora el servidor podrá  comprobar si el usuario y contraseña son válidos para identificar al usuario:

 public function identificacion() {  
      if ( array_key_exists(‘PHP_AUTH_USER’, $_SERVER) &&  
      array_key_exists(‘PHP_AUTH_PW’, $_SERVER) ) {  
           $usuario=$_SERVER['PHP_AUTH_USER'];  
           $pass=$_SERVER['PHP_AUTH_PW'];  
           if($usuario=="demo" && $pass == "demo") {  
                header("Location: ...");  
           }else{  
                mostrarVentanaLogin();  
           }  
      }else{  
           mostrarVentanaLogin();  
      }  
 }  

Evidentemente la comprobación de datos se haría sobre una base de datos o incluso sobre un fichero de contraseñas, pero no sobre dos constantes. Simplemente es a modo de ejemplo.


Entradas relacionadas

Seguridad PHP - Autenticación HTTP digest
Seguridad PHP - Autenticación HTTP vs PHP (formularios)

No hay comentarios:

Publicar un comentario