seguridades asp.net

14
DM Quito, agosto del 2011 Elaborado por: David Del Castillo SEGURIDADES EN APLICACIONES ASP.NET

Upload: david-del-castillo

Post on 25-Jun-2015

876 views

Category:

Technology


0 download

TRANSCRIPT

Page 1: Seguridades asp.Net

DM Quito, agosto del 2011

Elaborado por:

David Del Castillo

SEGURIDADES EN APLICACIONES ASP.NET

Page 2: Seguridades asp.Net

                 

Creación de un sitio Web con autenticación mediante formulario

La comprobación de seguridad se puede hacer de 3 formas:

1- Usando código directo, es decir, en el código de la aplicación tendremos los nombres y las claves.2- Los nombres de los usuarios y las claves estarán en el fichero Web.config.Se guardara un valor HASH que servirá para comprobar si la clave es "buena".3- Los nombres y claves se guardan en una base de datos.Incrementa el nivel de seguridad, las claves se guardan como valores HASH. SHA1 es utilizado por defecto en .NET

Page 3: Seguridades asp.Net

                 

1.- Usando código directamente:

La comprobación se hará al pulsar en el botón LOGIN, por tanto el código estará dentro del evento Click.Se debe importar la librería  System.Web.Security• Lo que se hace es comprobar si el nombre y la clave coinciden

con lo escrito en el código.• Además podemos obligar al usuario a “loguearse” cambiando

en el Web,config la forma de autenticación asi:<authentication mode="Windows" />- Cambiar por:<authentication mode="Forms">     <forms loginUrl="Login.aspx" /> </authentication>

Page 4: Seguridades asp.Net

                 

Y también en la parte de “autorización” de esta manera:<authorization>    <allow users="*" />Cambiar por: <authorization>    <deny users="?" /> <!-- solo los usuarios autenticados --></authorization>

Page 5: Seguridades asp.Net

                 

2.- Indicando los usuarios en Web.config:

- En el fichero Web.config podemos guardar los nombres de usuarios y las claves, de forma que el ASP.NET se encargue de comprobar si debe o no autorizarlo para entrar en nuestro sitio.- Las claves las vamos a guardar como un valor HASH, es decir, un

valor numérico que será único para cada una de las claves.- Este código deberá ir en la sección authentication. Asi:

<authentication mode="Forms">     <forms loginUrl="Login.aspx">         <credentials passwordFormat="SHA1">         <user name="pepe"            password="7550D35A69BE9ACA9AF9C29B880DC3ADEA01BEDC" />

Page 6: Seguridades asp.Net

                 

3.- Los nombres y claves se guardan en una base de datos.

- Solo deja iniciar una aplicación después de comprobar que el usuario y la clave introducidas son correctos. Pero para saber si la clave introducida es correcta, se busca en una base de datos.

Page 7: Seguridades asp.Net

                 

- Aquí el código de la función que valida el usuario y clave:

private bool comprobarUsuario(string nombre, string clave) { // Conectar a la base de datos SqlConnection cnn = null; // try { // Conectar a la base de datos de SQL Server // (la cadena debe estar inicializada previamente) cnn = new SqlConnection(cadenaCnn); cnn.Open(); // Definir la cadena que vamos a usar para comprobar // si el usuario y el password son correctos. // Utilizo parámetros para evitar inyección de código. System.Text.StringBuilder sel = new System.Text.StringBuilder(); // Usando COUNT(*) nos devuelve el total que coincide // con lo indicado en el WHERE, // por tanto, si la clave y el usuario son correctos, // devolverá 1, sino, devolverá 0 sel.Append("SELECT COUNT(*) FROM Usuarios "); sel.Append("WHERE Nombre = @Nombre AND Clave = @Clave"); // Definir el comando que vamos a ejecutar SqlCommand cmd = new SqlCommand(sel.ToString(), cnn); // Creamos los parámetros cmd.Parameters.Add("@Nombre", SqlDbType.NVarChar, 50); cmd.Parameters.Add("@Clave", SqlDbType.NVarChar, 40); // // Asignamos los valores recibidos como parámetro cmd.Parameters["@Nombre"].Value = nombre; cmd.Parameters["@Clave"].Value = clave; // // Ejecutamos la consulta // ExecuteScalar devuelve la primera columna de la primera fila // por tanto, devolverá el número de coincidencias halladas, // que si es 1, quiere decir que el usuario y el password son correctos. int t = Convert.ToInt32(cmd.ExecuteScalar()); // Cerramos la conexión cnn.Close(); // // Si el valor devuelto es cero // es que no es correcto. if( t == 0 ) { return false; }

private bool comprobarUsuario(string nombre, string clave) { // Conectar a la base de datos SqlConnection cnn = null; // try { // Conectar a la base de datos de SQL Server // (la cadena debe estar inicializada previamente) cnn = new SqlConnection(cadenaCnn); cnn.Open(); // Definir la cadena que vamos a usar para comprobar // si el usuario y el password son correctos. // Utilizo parámetros para evitar inyección de código. System.Text.StringBuilder sel = new System.Text.StringBuilder(); // Usando COUNT(*) nos devuelve el total que coincide // con lo indicado en el WHERE, // por tanto, si la clave y el usuario son correctos, // devolverá 1, sino, devolverá 0 sel.Append("SELECT COUNT(*) FROM Usuarios "); sel.Append("WHERE Nombre = @Nombre AND Clave = @Clave"); // Definir el comando que vamos a ejecutar SqlCommand cmd = new SqlCommand(sel.ToString(), cnn); // Creamos los parámetros cmd.Parameters.Add("@Nombre", SqlDbType.NVarChar, 50); cmd.Parameters.Add("@Clave", SqlDbType.NVarChar, 40); // // Asignamos los valores recibidos como parámetro cmd.Parameters["@Nombre"].Value = nombre; cmd.Parameters["@Clave"].Value = clave; // // Ejecutamos la consulta // ExecuteScalar devuelve la primera columna de la primera fila // por tanto, devolverá el número de coincidencias halladas, // que si es 1, quiere decir que el usuario y el password son correctos. int t = Convert.ToInt32(cmd.ExecuteScalar()); // Cerramos la conexión cnn.Close(); // // Si el valor devuelto es cero // es que no es correcto. if( t == 0 ) { return false; }

private bool comprobarUsuario(string nombre, string clave) { // Conectar a la base de datos SqlConnection cnn = null; // try { // Conectar a la base de datos de SQL Server

cnn = new SqlConnection(cadenaCnn); cnn.Open();// Definir la cadena que vamos a usar para comprobar si el usuario y el password son correctos.// Utilizo parámetros para evitar inyección de código. System.Text.StringBuilder sel = new System.Text.StringBuilder(); // Usando COUNT(*) nos devuelve el total que coincide // con lo indicado en el WHERE, // por tanto, si la clave y el usuario son correctos, // devolverá 1, sino, devolverá 0

Page 8: Seguridades asp.Net

                 

private bool comprobarUsuario(string nombre, string clave) { // Conectar a la base de datos SqlConnection cnn = null; // try { // Conectar a la base de datos de SQL Server // (la cadena debe estar inicializada previamente) cnn = new SqlConnection(cadenaCnn); cnn.Open(); // Definir la cadena que vamos a usar para comprobar // si el usuario y el password son correctos. // Utilizo parámetros para evitar inyección de código. System.Text.StringBuilder sel = new System.Text.StringBuilder(); // Usando COUNT(*) nos devuelve el total que coincide // con lo indicado en el WHERE, // por tanto, si la clave y el usuario son correctos, // devolverá 1, sino, devolverá 0 sel.Append("SELECT COUNT(*) FROM Usuarios "); sel.Append("WHERE Nombre = @Nombre AND Clave = @Clave"); // Definir el comando que vamos a ejecutar SqlCommand cmd = new SqlCommand(sel.ToString(), cnn); // Creamos los parámetros cmd.Parameters.Add("@Nombre", SqlDbType.NVarChar, 50); cmd.Parameters.Add("@Clave", SqlDbType.NVarChar, 40); // // Asignamos los valores recibidos como parámetro cmd.Parameters["@Nombre"].Value = nombre; cmd.Parameters["@Clave"].Value = clave; // // Ejecutamos la consulta // ExecuteScalar devuelve la primera columna de la primera fila // por tanto, devolverá el número de coincidencias halladas, // que si es 1, quiere decir que el usuario y el password son correctos. int t = Convert.ToInt32(cmd.ExecuteScalar()); // Cerramos la conexión cnn.Close(); // // Si el valor devuelto es cero // es que no es correcto. if( t == 0 ) { return false; }

private bool comprobarUsuario(string nombre, string clave) { // Conectar a la base de datos SqlConnection cnn = null; // try { // Conectar a la base de datos de SQL Server // (la cadena debe estar inicializada previamente) cnn = new SqlConnection(cadenaCnn); cnn.Open(); // Definir la cadena que vamos a usar para comprobar // si el usuario y el password son correctos. // Utilizo parámetros para evitar inyección de código. System.Text.StringBuilder sel = new System.Text.StringBuilder(); // Usando COUNT(*) nos devuelve el total que coincide // con lo indicado en el WHERE, // por tanto, si la clave y el usuario son correctos, // devolverá 1, sino, devolverá 0 sel.Append("SELECT COUNT(*) FROM Usuarios "); sel.Append("WHERE Nombre = @Nombre AND Clave = @Clave"); // Definir el comando que vamos a ejecutar SqlCommand cmd = new SqlCommand(sel.ToString(), cnn); // Creamos los parámetros cmd.Parameters.Add("@Nombre", SqlDbType.NVarChar, 50); cmd.Parameters.Add("@Clave", SqlDbType.NVarChar, 40); // // Asignamos los valores recibidos como parámetro cmd.Parameters["@Nombre"].Value = nombre; cmd.Parameters["@Clave"].Value = clave; // // Ejecutamos la consulta // ExecuteScalar devuelve la primera columna de la primera fila // por tanto, devolverá el número de coincidencias halladas, // que si es 1, quiere decir que el usuario y el password son correctos. int t = Convert.ToInt32(cmd.ExecuteScalar()); // Cerramos la conexión cnn.Close(); // // Si el valor devuelto es cero // es que no es correcto. if( t == 0 ) { return false; }

sel.Append("SELECT COUNT(*) FROM Usuarios "); sel.Append("WHERE Nombre = @Nombre AND Clave = @Clave"); // Definir el comando que vamos a ejecutar SqlCommand cmd = new SqlCommand(sel.ToString(), cnn); // Creamos los parámetros cmd.Parameters.Add("@Nombre", SqlDbType.NVarChar, 50); cmd.Parameters.Add("@Clave", SqlDbType.NVarChar, 40); // // Asignamos los valores recibidos como parámetro cmd.Parameters["@Nombre"].Value = nombre; cmd.Parameters["@Clave"].Value = clave; // // Ejecutamos la consulta // ExecuteScalar devuelve la primera columna de la primera fila // por tanto, devolverá el número de coincidencias halladas, // que si es 1, quiere decir que el usuario y el password son correctos. int t = Convert.ToInt32(cmd.ExecuteScalar()); // Cerramos la conexión cnn.Close(); // // Si el valor devuelto es cero // es que no es correcto. if( t == 0 ) { return false; }

Page 9: Seguridades asp.Net

                  Tanto el nombre del usuario como la clave, los pasamos como parámetros de la función. Y se buscarán en la base de datos tal y como los pasemos a esa función. Este código "supone" que accedemos a una base de datos que está indicada en la cadena de conexióncadenaCnn, y que en esa base de datos hay una tabla llamada Usuarios que al menos tiene dos campos, uno llamado Nombre que es del tipo nvarchar y que tiene una longitud de 50 caracteres y el otro llamado Claveque también es del tipo nvarchar y con una longitud de 40 caracteres.

Guardar los datos de la clave de forma encriptadaUna solución para que el valor de la clave no esté en texto normal, es encriptándola en formato SHA1 al estilo que lo hace ASP.NET.

Page 10: Seguridades asp.Net

                 

Y este es el código de la función generarClaveSHA1:

private string generarClaveSHA1(string nombre) { // Crear una clave SHA1 como la generada por // FormsAuthentication.HashPasswordForStoringInConfigFile // Adaptada del ejemplo de la ayuda en la descripción de SHA1 (Clase) UTF8Encoding enc = new UTF8Encoding(); byte[] data = enc.GetBytes(nombre); byte[] result; SHA1CryptoServiceProvider sha = new SHA1CryptoServiceProvider(); // This is one implementation of the abstract class SHA1. result = sha.ComputeHash(data); // // Convertir los valores en hexadecimal // cuando tiene una cifra hay que rellenarlo con cero // para que siempre ocupen dos dígitos. StringBuilder sb = new StringBuilder(); for(int i= 0; i< result.Length; i++) { if( result[i] < 16 ) { sb.Append("0"); } sb.Append(result[i].ToString("x")); } // return sb.ToString().ToUpper(); }

Para que ese código funcione hay que tener una importación al espacio de nombres, System.Security.Cryptography que es donde se define la clase SHA1CryptoServiceProvider y también a System.Text que es donde se definen las clases StringBuilder y UTF8Encoding.

Page 11: Seguridades asp.Net

                 

Crear una aplicación Web que utilice un Web Form para realizar la autenticación de los usuarios que quieran navegar por el sitio Web que la utilice.

Page 12: Seguridades asp.Net

12

- Creación del proyecto y de la página de Login- Crea un nuevo proyecto en Visual Studio, selecciona el lenguaje y elije el de Aplicación Web.- Pedira un nombre para crearlo en el localhost, en el ejm sera = pruebaLogin.-Cuando Visual Studio termine de crear el sitio, se mostrará el proyecto "inicial“-

Page 13: Seguridades asp.Net

13

- Añadimos dos etiquetas, dos cajas de textos y un botón, asi:

Page 14: Seguridades asp.Net

14

-Para añadir una nueva página, en el menú Proyecto, -selecciona Agregar Web Forms... esto mostrará un diálogo como el mostrado en la figura (el primer caso: Default)