|
|
Línea 3: |
Línea 3: |
| __NOTOC__ | | __NOTOC__ |
| {{:Usuario:ManuelRomero/php/autentificacion/nav}} | | {{:Usuario:ManuelRomero/php/autentificacion/nav}} |
− |
| |
− |
| |
− | ===Qué es autentificarse===
| |
− | *Por autentificarse vamos a entender un mecanismo por el cual el servidor web puede estar relativamente confiado en que está siendo consultado por una determinada máquina y/o persona
| |
− | *Por ejemplo podemos visitar esta página y ver diferentes modos en los que piden autentificarse
| |
− | https://www.tractis.com/login
| |
− | *Modos de autentificarse
| |
− | #contraseña y usuario
| |
− | #Dni digital
| |
− | #Certificados digitales de usuario
| |
− | ...
| |
− | *Nosotros en este tema usaremos el módo de contraseña y usuario. En dos temas posteriores, cuando veamos servicios web usaremos otro sistema como google, igualmente se podría usar la cuenta de facebook o twiter para identificarte.
| |
− | *La responsabilidad de exigir una clave de acceso puede recaer sobre el servidor web con los módulos de seguridad
| |
− | *En este caso restringimos el acceso a la página o sitio web
| |
− | *Otra opción habitual es tener un sitio con cierto contendo y en el sitio dar la posibilidad de identificarse / registrarse.
| |
− | *A usuarios identificados se les ofrece otro contendio diferente.
| |
− | Respecto a estos conceptos vamos a trabajar este tema que es el primero de tres aspectos del tema 4
| |
− |
| |
− |
| |
− | ===protocolo http vs https===
| |
− | *Este es un concepto importante
| |
− | *La seguridad del envío de datos es otro aspecto diferente del tema de la autentificación
| |
− | *En seguridad entre otros aspectos tenemos
| |
− | #'''''La autentificación''''' mecanismos por los cuales podemos confiar en que quien se ha identificado es conocido para el sistema
| |
− | #'''''La confidencialidad''''' son mecanismos con los que podemos confiar en que nadie puede ver el contendio de la información ni modificarla durante la transmisión.
| |
− | *Ambos mecanismos debería de trabajar conjuntamente. Por ejemplo si yo envío una contraseña para identificarse, pero con un sniffer alguien la puede capturar y ver en claro, no coneseguimos nada de seguridad .
| |
− | *Para la transmisión segura se emplea el protocolo https.
| |
− | *Este tema se estudia en el módulo de despliegue de aplicaciones web.
| |
− | *Nosotros usaremos http sin cifrar, pero se insiste en que no es segura la transmisión, pues podría ser objetivo de espía informático.
| |
− |
| |
− | ====Autentificación por el servidor web====
| |
− | *Es el propio servidor '''''http''''' quien nos ofrece este método de autentifiación.
| |
− | *Seguramente ya lo habéis estudiado en despliegue, pero lo vamos a comentar
| |
− | *El mecanismo es sencillo.
| |
− | #Definir los usarios con acceso permitido
| |
− | #Se puede indicar a qué recursos tiene acceso el usuario en concreto
| |
− | #el código http en caso de acceso restringido es el 401
| |
− | #El navegador al recigir ese código solicita credenciales
| |
− | *El servidor recibe estas credenciales y las almacena en sus variables superglobales para futuras solicituds
| |
− | ;Crear la lista de usuarios
| |
− | *Usamos la herramienta '''''htpasswd''''' para crear un fichero con los usarios y sus contraseñas
| |
− | http://httpd.apache.org/docs/2.4/es/howto/auth.html
| |
− | *Este comando tiene una serie de opciones que podemos ver en línea de comandos sin mas que esciribr su nombre
| |
− | <source lang=bash>
| |
− | Usage:
| |
− | htpasswd [-cmdpsD] passwordfile username
| |
− | htpasswd -b[cmdpsD] passwordfile username password
| |
− |
| |
− | htpasswd -n[mdps] username
| |
− | htpasswd -nb[mdps] username password
| |
− | -c Create a new file.
| |
− | -n Don\'t update file; display results on stdout.
| |
− | -m Force MD5 encryption of the password (default).
| |
− | -d Force CRYPT encryption of the password.
| |
− | -p Do not encrypt the password (plaintext).
| |
− | -s Force SHA encryption of the password.
| |
− | -b Use the password from the command line rather than prompting for it.
| |
− | -D Delete the specified user.
| |
− | On other systems than Windows, NetWare and TPF the '-p' flag will probably not work.
| |
− | The SHA algorithm does not use a salt and is less secure than the MD5 algorithm.
| |
− | </source>
| |
− | *importante es la opción -c para crear el fichero
| |
− | *Para incorporar nuevos usuarios se escribe sin opcion y se añaden
| |
− | *Por seguridad es importante añadir el fichero en una ubicación fuera del servidor web.
| |
− |
| |
− | {{Actividad|
| |
− | crea un fichero llamado misUsuarios y añade 3 usuarios maria/maria nieves/nieves sara/sara
| |
− |
| |
− | <source lang=bash>
| |
− | sudo htpasswd -c misUsuarios maria
| |
− | ....
| |
− | sudo htpasswd nieves
| |
− | ....
| |
− | sudo htpasswd nieves
| |
− | </source>
| |
− |
| |
− | }}
| |
− | ;Indicar los recursos restringidos al servidor apache, la mejor opción (no la única)es crear un directorio .htacess, en le directorio en el que se encuentren los recursos compartidos
| |
− | *Para indicar los recursos restringidos usarmos las siguientes directivas ya conocidas
| |
− | *'''''AuthName''''' Nombre de dominio de la authentificación
| |
− | *'''''AuthType''''' Tipo de autentificación '''Basic''' y más segura '''Dijest'''
| |
− | *'''''AuthUserFile'''''Ruta del fichero de los usuarios con permiso'''''
| |
− | *'''''Require''''' valid-user o usuarios concretos de la lista que sí que tendrán acceso al recuros
| |
− | *Ademas en el fichero de confituración de apache debemos activar la directiva '''''AllowOverride'''''
| |
− | http://httpd.apache.org/docs/2.4/es/mod/core.html#allowoverride
| |
− | {{Actividad|
| |
− | Crea un sencillo sitio web que me rediriga a 4 páginas:
| |
− | *'''''Información General''''' : Tendrá acceso todo el mundo
| |
− | *'''''Información restirngida''''': Sólo tendŕan acceso maría nieves y sara
| |
− | *'''''Información Sara''''' : Tendrá acceso solo el usuario sara
| |
− | *'''''Información de grupo''''' : Tendrá acceso los usuarios maría y nieves
| |
− | }}
| |
− |
| |
− | ====PHP accediendo a información http====
| |
− | *Desde el código de php podemos acceder a la información facilitada por el servidor php.
| |
− | *La matriz asociativa variable superglobal $_SERVER contiene esta información
| |
− | *Concretamente los índices
| |
− | #'''''PHP_AUTH_USER''''' Es el nombre del usuario
| |
− | #'''''PHP_AUTH_PW''''' Es la password del usuario
| |
− | #'''''AUTH_TYPE''''' Es el tipo de seguridad utilizado
| |
− | {{Actividad|
| |
− | *Modifica la página restringida para ver el usuario y password así como el método usado de autentifiacion
| |
− | *El código que habría que añadir
| |
− | <source lang=php>
| |
− | <?php
| |
− | echo "te has autentificado como:<br/>";
| |
− |
| |
− | echo "Usuario: ". $_SERVER['PHP_AUTH_USER']."<br/>";
| |
− | echo "Password: ". $_SERVER['PHP_AUTH_PW']."<br/>";
| |
− | echo "Tipo de autentificacion: ". $_SERVER['AUTH_TYPE'];
| |
− | ?>
| |
− | </source>
| |
− |
| |
− | }}
| |
− |
| |
− | ===Usar función header para la autentifiación===
| |
− | *La referencia de la función header
| |
− | http://es.php.net/manual/es/function.header.php
| |
− | *Vamos a usarla para unas acciones concretas
| |
− | ;Modificar el texto de error
| |
− | *En este caso no vamos a usar el fichero .htaccess
| |
− | *Cuando accedemos a una página y no nos hemos identificado aparece un error 401
| |
− | *Vamos a solicitar una autentificación de tipo basic
| |
− | *Para ello especificamos la cabecera WWW-Authenticate
| |
− | *Ademas de especificar el modo de autentifación ponemos el mensaje que verá el usuario
| |
− | <source lang=php>
| |
− | header('WWW-Authenticate: Basic Realm="Página de acceso restringido. Necesrias credenciales"');
| |
− | </source>
| |
− | *Para no mostrar la página solicitada se envía un error 401, lo que provoca que se solicite un usuario y contraseña antes de visualizar el resto de la página.
| |
− | *El códgio quedaría
| |
− | <source lang=php>
| |
− | header('HTTP/1.0 401 Unauthorized');
| |
− | </source>
| |
− | *El código completo quedaría
| |
− | <source lang=php>
| |
− | <?php
| |
− | if (!isset($_SERVER['PHP_AUTH_USER'])) {
| |
− | header('WWW-Authenticate: Basic Realm="Contenido restringido"');
| |
− | header('HTTP/1.0 401 Unauthorized');
| |
− | echo "Usuario no reconocido!";
| |
− | exit;
| |
− | }
| |
− | ?>
| |
− | </source>
| |
− | *Ahora debemos poder especificar cual va a ser el usuario esperado en esta página
| |
− | *Por ejemplo en la página anterior insertamos un usario cualquiera y una password cualquiera entraremos ya que no comparamos con nadie
| |
− | <source lang=php>
| |
− | <?php
| |
− | echo"Nombre de usuario: ".$_SERVER['PHP_AUTH_USER'] ."<br />";
| |
− | echo"Contraseña: ".$_SERVER['PHP_AUTH_PW'] ."<br />";
| |
− | ?>
| |
− | </source>
| |
− | ;Verficar el usuario y contraseñad
| |
− | *Con el siguiente código verificaríamos el usuario y contraseña usando el modo de header
| |
− | <source lang=php>
| |
− | <?php
| |
− | if ($_SERVER['PHP_AUTH_USER']!='manolo' || $_SERVER['PHP_AUTH_PW']!='passManolo.') {
| |
− | header('WWW-Authenticate: Basic Realm="Contenido restringido"');
| |
− | header('HTTP/1.0 401 Unauthorized');
| |
− | echo "Usuario no reconocido!";
| |
− | exit;
| |
− | }
| |
− | ?>
| |
− | </source>
| |
− | *Esto nos podría servir, puesto que el código no se envía al cliente, y él nunca podría ver la password, ni el usuario
| |
− | *No obstante, siempre será una opción más segura, y más versátil tener el usuario almacenado en una base de datos
| |
− | *Podríamos crear la siguiente tabla en nuestra base de datos dwes
| |
− | <source lang=sql>
| |
− |
| |
− | -- Seleccionamos la base de datos
| |
− | USE dwes;
| |
− | -- Creamos la tabla
| |
− | CREATE TABLE usuarios (
| |
− | usuario VARCHAR(20) NOT NULL PRIMARY KEY,
| |
− | contrasena VARCHAR(32) NOT NULL
| |
− | ) ENGINE = INNODB;
| |
− |
| |
− | -- Creamos el usuario dwes
| |
− | INSERT INTO usuarios (usuario, contrasena) VALUES
| |
− | ('dwes', 'e8dc8ccd5e5f9e3a54f07350ce8a2d3d');
| |
− | </source>
| |
− | *Con esto estaríamos creando el usuario '''''dwes''''' y su password '''''abc123.''''', el '''''punto final''''', también forma parte de la contraseña
| |
− | *Si queremos usar una base de datos es importante cifrar el contenido de la password
| |
− | *Para ello usaremos la función md5, cuya información oficial es
| |
− | http://es.php.net/manual/es/function.md5.php
| |
− | *Para usarla simplemente le haremos '''''md5(string)''''', y veremos el hash de dicho string
| |
− | {{Actividad|
| |
− | *Utilizando la extension mysqli, solicitamos credenciales para los usuarios en las diferentes páginas del ejercicio anterior, de modo que si bien el usuario o la pass son incorrecta, se vuelven a pedir credenciales.
| |
− | *Para obtener el código md5 y crearlo en la base de datos, podemos usar esta página
| |
− | http://www.md5online.es/cifrar-md5.html
| |
− | ==Solución propuesta==
| |
− | <source lang=php>
| |
− | <!DOCTYPE html>
| |
− | <?php
| |
− | <!DOCTYPE html>
| |
− | <?php
| |
− | // Si el usuario aún no se ha autentificado, pedimos las credenciales
| |
− | //Observa que escribimos esto antes de escribier ninguna salida
| |
− | //Esto es importante si se usa la función header
| |
− | if (!isset($_SERVER['PHP_AUTH_USER'])) {
| |
− | header('WWW-Authenticate: Basic realm="Contenido restringido"');
| |
− | header("HTTP/1.0 401 Unauthorized");
| |
− | exit;
| |
− | }
| |
− | // Si ya ha enviado las credenciales, las comprobamos con la base de datos
| |
− | else {
| |
− | // Conectamos a la base de datos
| |
− |
| |
− | $conexion = new mysqli("localhost", "root", "root", "dwes");
| |
− | $error = $conexion->connect_errno;
| |
− | // Si se estableció la conexión
| |
− | if ($error == null) {
| |
− | //Realizamos una consulta preparada
| |
− | $consulta = $conexion->stmt_init();
| |
− | // Ejecutamos la consulta para comprobar si existe
| |
− | // esa combinación de usuario y contraseñ
| |
− | $sql = <<<SQL
| |
− | SELECT usuario FROM usuarios
| |
− | WHERE usuario = ? AND
| |
− | contrasena = ?
| |
− | SQL;
| |
− |
| |
− | $usuario = $_SERVER['PHP_AUTH_USER'];
| |
− | $pass = md5($_SERVER['PHP_AUTH_PW']);
| |
− | $consulta->prepare($sql);
| |
− | $consulta->bind_param("ss", $usuario, $pass);
| |
− | $consulta->execute();
| |
− | $consulta->store_result();
| |
− | if ($consulta->num_rows === 0) {
| |
− |
| |
− | header('WWW-Authenticate: Basic realm="Contenido restringido"');
| |
− | header("HTTP/1.0 401 Unauthorized");
| |
− | //Esto solo se visualizará si damos a cancelar del formulario de autentificación
| |
− | $consulta->close();
| |
− | $conexion->close();
| |
− | echo "<h1> Usuario y password no autorizado reintentelo </h1>";
| |
− | exit;
| |
− | }
| |
− | $consulta->close();
| |
− | $conexion->close();
| |
− | }//End error =null
| |
− | }//End else de if !isset .....
| |
− | ?>
| |
− | <html>
| |
− | <head>
| |
− | <meta http-equiv="content-type" content="text/html; charset=UTF-8">
| |
− | <title>Ejemplo Tema 4: Utilización de MySQL para autentificación HTTP</title>
| |
− | <link href="dwes.css" rel="stylesheet" type="text/css">
| |
− | </head>
| |
− | <body>
| |
− | <?php
| |
− | echo "Nombre de usuario: " . $_SERVER['PHP_AUTH_USER'] . "<br />";
| |
− | echo "Hash de la contraseña: " . md5($_SERVER['PHP_AUTH_PW']) . "<br />";
| |
− | ?>
| |
− | </body>
| |
− | </html>
| |
− | </source>
| |
− | }}
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− |
| |
− | |}
| |