|
|
Línea 1: |
Línea 1: |
− | {{TEP}}
| |
− |
| |
− |
| |
| {{:Usuario:ManuelRomero/php/nav}} | | {{:Usuario:ManuelRomero/php/nav}} |
| | | |
Línea 203: |
Línea 200: |
| *Para obtener el código md5 y crearlo en la base de datos, podemos usar esta página | | *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 | | http://www.md5online.es/cifrar-md5.html |
| + | ==Solución propuesta== |
| + | <source lang=php> |
| + | <!DOCTYPE html> |
| + | <?php |
| + | // Si el usuario aún no se ha autentificado, pedimos las credenciales |
| + | //Observa que escribimos esto antes de escribir 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 entramos en el else es por que ya se han enviado las credenciales, |
| + | //En este caso 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 continuamos, si no no hacemos nada ???? |
| + | 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ña |
| + | $sql = <<<SQL |
| + | SELECT usuario FROM usuarios |
| + | WHERE usuario = ? |
| + | AND |
| + | contrasena = ? |
| + | SQL; |
| + | //Recordad que en Heredoc la palabra semilla tiene sus restricciones de ubicación |
| + | //Obtenemos los valores de usuario y contraseña de los enviados previamente |
| + | $usuario = $_SERVER['PHP_AUTH_USER']; |
| + | $pass = md5($_SERVER['PHP_AUTH_PW']); |
| + | |
| + | $consulta->prepare($sql); |
| + | $consulta->bind_param("ss", $usuario, $pass); |
| + | $consulta->execute(); |
| + | //El store_result(), aquí no hace falta, pero tampoco estorba. |
| + | $consulta->store_result(); |
| + | |
| + | if ($consulta->num_rows === 0) { //Estricto para evitar que un null o false también de ok |
| + | //Si ese usuario y pass no coinciden lo volvemos a solicitar |
| + | header('WWW-Authenticate: Basic realm="Contenido restringido"'); |
| + | header("HTTP/1.0 401 Unauthorized"); |
| + | //Este código solo se verá si damos al botón de cancelar en la solicitud de credenciales |
| + | echo "<h1> Usuario y password no autorizado</h1>" |
| + | |
| + | exit; |
| + | } |
| + | } |
| + | } |
| + | ?> |
| + | <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" " |
| + | http://www.w3.org/TR/html4/loose.dtd"> |
| + | <!-- Desarrollo Web en Entorno Servidor --> |
| + | <!-- Tema 4 : Desarrollo de aplicaciones web con PHP --> |
| + | <!-- Ejemplo: Utilización de MySQL para autentificación HTTP --> |
| + | <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> |
| }} | | }} |
| | | |
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
- 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
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.
- 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
sudo htpasswd -c misUsuarios maria
....
sudo htpasswd nieves
....
sudo htpasswd nieves
|
- 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
- AuthUserFileRuta 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
<?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'];
?>
|
- 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
header('WWW-Authenticate: Basic Realm="Página de acceso restringido. Necesrias credenciales"');
- 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
header('HTTP/1.0 401 Unauthorized');
- El código completo quedaría
<?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;
}
?>
- 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
<?php
echo"Nombre de usuario: ".$_SERVER['PHP_AUTH_USER'] ."<br />";
echo"Contraseña: ".$_SERVER['PHP_AUTH_PW'] ."<br />";
?>
- Verficar el usuario y contraseñad
- Con el siguiente código verificaríamos el usuario y contraseña usando el modo de header
<?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;
}
?>
- 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
-- 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');
- 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
<!DOCTYPE html>
<?php
// Si el usuario aún no se ha autentificado, pedimos las credenciales
//Observa que escribimos esto antes de escribir 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 entramos en el else es por que ya se han enviado las credenciales,
//En este caso 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 continuamos, si no no hacemos nada ????
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ña
$sql = <<<SQL
SELECT usuario FROM usuarios
WHERE usuario = ?
AND
contrasena = ?
SQL;
//Recordad que en Heredoc la palabra semilla tiene sus restricciones de ubicación
//Obtenemos los valores de usuario y contraseña de los enviados previamente
$usuario = $_SERVER['PHP_AUTH_USER'];
$pass = md5($_SERVER['PHP_AUTH_PW']);
$consulta->prepare($sql);
$consulta->bind_param("ss", $usuario, $pass);
$consulta->execute();
//El store_result(), aquí no hace falta, pero tampoco estorba.
$consulta->store_result();
if ($consulta->num_rows === 0) { //Estricto para evitar que un null o false también de ok
//Si ese usuario y pass no coinciden lo volvemos a solicitar
header('WWW-Authenticate: Basic realm="Contenido restringido"');
header("HTTP/1.0 401 Unauthorized");
//Este código solo se verá si damos al botón de cancelar en la solicitud de credenciales
echo "<h1> Usuario y password no autorizado</h1>"
exit;
}
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
http://www.w3.org/TR/html4/loose.dtd">
<!-- Desarrollo Web en Entorno Servidor -->
<!-- Tema 4 : Desarrollo de aplicaciones web con PHP -->
<!-- Ejemplo: Utilización de MySQL para autentificación HTTP -->
<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>
|
|
|