Pop

33.Aplicaciones web.Página de Login (2).Curso de C# con Visual Studio 2017.

33- . Aplicaciones web.Página de Login (2)

   - En este capítulo del curso de programación en c# con visual studio 2017 vamos a ver como crear un mecanismo para actualizar passwords que tengamos almacenadas en una base de datos.Para ello generamos una url con el email del usuario cifrado que pondremos como parametro en la querystring, y creamos otra página que valide y actualice en base de datos. Los pasos para cambiar la password son los siguientes:

  1. El usuario hace click en el enlace ¿Olvido su contraseña?
  2. Al hacer click solicitamos un email con el que validaremos que usuario existe en nuestro el sistema.
  3. En el caso que el usuario exista generamos una url  con el email cifrado incrustado en ella como parametro encriptado.Esta url apuntará a una página que tenemos creada para actualizar la password en la base de datos.
  4. Esta url debería llegar al usuario via email.
  5. Cuando el usuario hace clic en esta url validamos el email que nos llega encriptado no ha sido alterado (esta comprobación la hacemos para evitar en la medida de lo posble los bot y ataques varios).
  6. Si todo es correcto apareceran en pantalla dos cajas de texto donde el usuario debe poner la nueva password.
  7. Despues de poner la password pulsando el botón actualizaremos en  la base de datos.
- En el video muestro como se hacen estos pasos:


- Os dejo el código completo del ejmplo del Login:

  • Default.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="GestionVarios.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
           <asp:Label runat="server" ID="lblErrorREcordar"></asp:Label>
        <div id="divLogin" runat="server">
            <table width="200" border="0" cellspacing="0" cellpadding="0">
                <tr>
                    <td height="24">
                        <table width="200" border="0" cellspacing="0" cellpadding="0">
                            <tr>
                                <td width="75" align="right" valign="top">Usuario:&nbsp;&nbsp;&nbsp;&nbsp;
                                </td>
                                <td width="125">
                                    <asp:TextBox ID="txtUsuario" runat="server"></asp:TextBox>
                                    <asp:RegularExpressionValidator ID="mvalUsuarioValida" runat="server"
                                        ErrorMessage="Usuario incorrecto" ControlToValidate="txtUsuario"
                                        ValidationExpression="\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*" Display="Dynamic" ForeColor="Red"></asp:RegularExpressionValidator>
                                    <asp:RequiredFieldValidator ID="mvalRequiereUsuario" runat="server" ErrorMessage="<br>Indique el usuario" ControlToValidate="txtUsuario" Display="Dynamic" ForeColor="Red"></asp:RequiredFieldValidator>
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
                <tr>
                    <td height="24">
                        <table width="200" border="0" cellspacing="0" cellpadding="0">
                            <tr>
                                <td width="75" align="right" valign="top" class="texto_news">Password:&nbsp;
                                </td>
                                <td width="125">
                                    <asp:TextBox ID="txtPassword" runat="server" TextMode="Password"></asp:TextBox>
                                    <asp:RegularExpressionValidator ID="mvalPasswordValida" runat="server" ErrorMessage="<br>Contraseña incorrecta" ControlToValidate="txtPassword" ValidationExpression="\w+.{5,}" Display="Dynamic" ForeColor="Red"></asp:RegularExpressionValidator>
                                    <asp:RequiredFieldValidator ID="mvalRequiereContraseña" runat="server" ErrorMessage="<br>Indique la contraseña" ControlToValidate="txtPassword" Display="Dynamic" ForeColor="Red"></asp:RequiredFieldValidator>
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
                <tr>
                    <td align="right" valign="middle">
                        <asp:Button runat="server" Text="Inicio sesion" OnClick="Unnamed1_Click" />
                        <br />
                        <asp:Label runat="server" ID="lblError"></asp:Label>
                    </td>
                </tr>

                <tr>
                    <td>
                        <table width="200" border="0" cellspacing="0" cellpadding="0">
                            <tr>
                                <td height="22" align="left"><a href="~/AltaUsuario.aspx" runat="server" target="_blank"><b>Darse de alta </b></a></td>
                            </tr>
                            <tr>
                                <td align="left">
                                    <asp:LinkButton ID="lnkOlvido" runat="server"
                                        CausesValidation="false" OnClick="lnkOlvido_Click"><b>¿Olvidó su password?</b></asp:LinkButton>
                                </td>
                            </tr>
                        </table>
                    </td>
                </tr>
            </table>
        </div>
        <div id="divRecordar" runat="server" visible="false">
            <table id="mOlvidoPassword" width="400" border="0" cellpadding="0" cellspacing="0">
                <tr>
                    <td>
                        <br />
                        Si ha olvidado su pass, indíquenos el email con el que se registró:
                    </td>
                </tr>
                <tr>
                    <td width="200" align="left" class="texto_news">
                        <br />
                        Email<br />
                        <asp:TextBox ID="txtRecuperacion" runat="server"  Width="200px"></asp:TextBox>

                    </td>
                </tr>
                <tr>
                    <td align="right" valign="middle" height="30px">
                        <asp:Button runat="server" ID="btnRecordar" Text="Recordar pass" OnClick="btnRecordar_Click" />
                           <br />
                    
                    </td>
                </tr>
            </table>
        </div>
    </form>
</body>
</html>

  •  Default.aspx.cs:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Net.Mail;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace GestionVarios
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Unnamed1_Click(object sender, EventArgs e)
        {
           
            SqlConnection conexion = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);
            string usuarioGuardadaBaseDatos  = String.Empty;
            byte[] passGuardadaBaseDatos = null;
            try
            {
                conexion.Open();
                SqlCommand com = conexion.CreateCommand();
                com.CommandType = System.Data.CommandType.StoredProcedure;
                com.CommandText = "dbo.ValidarUsuario";
               com.Parameters.Add("@email", SqlDbType.VarChar, 255).Value = txtUsuario.Text;

                SqlDataReader reader = com.ExecuteReader();

                if (reader.Read())
                {
                    usuarioGuardadaBaseDatos = reader["email"].ToString();
                    if(usuarioGuardadaBaseDatos!=String.Empty)
                    passGuardadaBaseDatos = (byte[])reader["pass"];
                  
                }
                else
                    throw new Exception("Usuario o pass incorrecto.");

                if(usuarioGuardadaBaseDatos!=String.Empty && ValidarDatos(usuarioGuardadaBaseDatos, passGuardadaBaseDatos))
                {
                    Response.Redirect("~/Pedidos.aspx");
                    Response.End();
               }
                else
                    throw new Exception("Usuario o pass incorrecto.");

            }
            catch (Exception ex)
            {
                lblError.Text = "Se produjo un error iniciando sesion:" + ex.Message;
                lblError.ForeColor = Color.Red;
             
            }
            finally
            {
                if (conexion != null && conexion.State == System.Data.ConnectionState.Open)
                    conexion.Close();

                conexion.Dispose();
            }

          
        }

        private Boolean ValidarDatos(string usuario, byte[] pass)
        {
            Boolean usuarioCorrecto = false;
            string passDescifrada = String.Empty;

            String miclave = ConfigurationManager.AppSettings["clave"];
            byte[] claveCifrado = System.Text.Encoding.ASCII.GetBytes(miclave);
            Cifrado c = new Cifrado(claveCifrado);
            passDescifrada = c.descifrar(pass);

      
            if (passDescifrada == txtPassword.Text && txtUsuario.Text == usuario)
                usuarioCorrecto = true;

            return usuarioCorrecto;
        }

        protected void lnkOlvido_Click(object sender, EventArgs e)
        {
            divRecordar.Visible = true;
            divLogin.Visible = false;
        }

        protected void btnRecordar_Click(object sender, EventArgs e)
        {
            SqlConnection conexion = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);
           try
            {
                conexion.Open();
                SqlCommand com = conexion.CreateCommand();
                com.CommandType = System.Data.CommandType.StoredProcedure;
                com.CommandText = "dbo.ValidarUsuario";
                com.Parameters.Add("@email", SqlDbType.VarChar, 255).Value = txtRecuperacion.Text;

                SqlDataReader reader = com.ExecuteReader();

                if (reader.Read())
                {
                
                    EnviarDatos(txtRecuperacion.Text);

                }
                else
                    throw new Exception("Email no registrado en el sistema");

            }
            catch (Exception ex)
            {
                lblErrorREcordar.Text = "Se produjo un error recuperando password:" + ex.Message;
                lblErrorREcordar.ForeColor = Color.Red;

            }
            finally
            {
                if (conexion != null && conexion.State == System.Data.ConnectionState.Open)
                    conexion.Close();

                conexion.Dispose();
            }


        }

        protected void EnviarDatos(string Email)
        {
            try
            {
                string url = "https:";
                DateTime fecha = DateTime.Now;
                String miclave = ConfigurationManager.AppSettings["clave"];
                byte[] claveCifrado = System.Text.Encoding.ASCII.GetBytes(miclave);
                Cifrado c = new Cifrado(claveCifrado);
                byte[] emailCif= c.cifrar(Email);
                string encoded = HttpUtility.UrlEncode(Convert.ToBase64String(emailCif));

                // CODIGO QUE ENVIARIA UN MAIL CON LA URL.ESTA HECHO EN EL KEYLOGGER
                lblErrorREcordar.Text = url + "//" + Request.Url.Host +":"+Request.Url.Port+ "/RecuperarPass.aspx?p=" + encoded ;

            }

            catch (Exception ex)
            {

                lblErrorREcordar.Text = "Se produjo un error recuperando password:" + ex.Message;
                lblErrorREcordar.ForeColor = Color.Red;
            }
        }
    }

      
}

  • RecuperarPass.aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="RecuperarPass.aspx.cs" Inherits="GestionVarios.RecuperarPass" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:Label ID="Label1" runat="server" Text="Nueva pass"></asp:Label>
            <asp:TextBox ID="txtPass1" runat="server" TextMode="Password"></asp:TextBox>
            <asp:RegularExpressionValidator ID="mvalPasswordValida" runat="server" ErrorMessage="<br>Contraseña incorrecta" ControlToValidate="txtPass1" ValidationExpression="\w+.{5,}" Display="Dynamic" ForeColor="Red"></asp:RegularExpressionValidator>
            <asp:RequiredFieldValidator ID="mvalRequiereContraseña" runat="server" ErrorMessage="<br>Indique la contraseña" ControlToValidate="txtPass1" Display="Dynamic" ForeColor="Red"></asp:RequiredFieldValidator>
            <br />
            <asp:Label ID="Label2" runat="server" Text="Confirmar pass" TextMode="Password"></asp:Label>
            <asp:TextBox ID="txtpass2" runat="server" TextMode="Password"></asp:TextBox>
            <asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ErrorMessage="<br>Contraseña incorrecta" ControlToValidate="txtpass2" ValidationExpression="\w+.{5,}" Display="Dynamic" ForeColor="Red"></asp:RegularExpressionValidator>
            <asp:RequiredFieldValidator ID="RequiredFieldValidator1" runat="server" ErrorMessage="<br>Indique la contraseña" ControlToValidate="txtpass2" Display="Dynamic" ForeColor="Red"></asp:RequiredFieldValidator>
             <asp:CompareValidator ID="mcomPasswords" runat="server" ErrorMessage="Las contraseñas no son iguales." Display="Dynamic" ControlToCompare="txtPass1" ControlToValidate="txtpass2" ForeColor="Red"></asp:CompareValidator>
            <br />
            <asp:Button ID="Button1" runat="server" Text="Cambiar pass" OnClick="Button1_Click" />
            <asp:Label runat="server" ID="lblMensaje"></asp:Label>
        </div>
    </form>
</body>
</html>

  • RecuperarPass.aspx.cs:
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace GestionVarios
{
    public partial class RecuperarPass : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

            string mail = obtenerMail();
            validarEmail(mail);

           

        }

        private string obtenerMail()
        {
            byte[] byteArray = Convert.FromBase64String(Request.QueryString["p"]);
            string value = System.Text.Encoding.UTF8.GetString(byteArray);
            String miclave = ConfigurationManager.AppSettings["clave"];
            byte[] claveCifrado = System.Text.Encoding.ASCII.GetBytes(miclave);
            Cifrado c = new Cifrado(claveCifrado);
            string mail = c.descifrar(byteArray);
            return mail;
        }

        private void validarEmail(string email)
        {
            SqlConnection conexion = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);
            try
            {
                conexion.Open();
                SqlCommand com = conexion.CreateCommand();
                com.CommandType = System.Data.CommandType.StoredProcedure;
                com.CommandText = "dbo.ValidarUsuario";
                com.Parameters.Add("@email", SqlDbType.VarChar, 255).Value = email;

                SqlDataReader reader = com.ExecuteReader();
               
                if (!reader.Read())
                        throw new Exception("Email no registrado en el sistema");

               

            }
            catch (Exception ex)
            {
                Response.Write(ex.Message);
                Response.End();

            }
            finally
            {
                if (conexion != null && conexion.State == System.Data.ConnectionState.Open)
                    conexion.Close();

                conexion.Dispose();
            }
        }
        private byte[] cifrar(string cadenaAcifrar)
        {
            String miclave = ConfigurationManager.AppSettings["clave"];
            byte[] claveCifrado = System.Text.Encoding.ASCII.GetBytes(miclave);
            Cifrado c = new Cifrado(claveCifrado);
            byte[] b = c.cifrar(cadenaAcifrar);
            return b;
        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            SqlConnection conexion = new SqlConnection(ConfigurationManager.ConnectionStrings["EmpresaConnectionString"].ConnectionString);
            try
            {
                conexion.Open();
                SqlCommand com = conexion.CreateCommand();
                com.CommandType = System.Data.CommandType.StoredProcedure;
                com.CommandText = "dbo.ModificarPass";
                com.Parameters.Add("@email", SqlDbType.VarChar, 255).Value = obtenerMail();
                com.Parameters.Add("@pass", SqlDbType.VarBinary, 8000).Value = cifrar(txtPass1.Text);
                com.ExecuteNonQuery();

                lblMensaje.Text = "Password cambiada";
                lblMensaje.ForeColor = Color.Green;
            }
            catch (Exception ex)
            {
                lblMensaje.Text= ex.Message;
             

            }
            finally
            {
                if (conexion != null && conexion.State == System.Data.ConnectionState.Open)
                    conexion.Close();

                conexion.Dispose();
            }
        }
   
    }
}

  • Cifrado.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Web;

namespace GestionVarios
{
    public class Cifrado
    {
        Aes miAes = null;

        public Cifrado(byte[] clave)
        {
            miAes = Aes.Create();
            miAes.Key = clave;
            miAes.IV = clave;
        }

        public byte[] cifrar(string original)
        {
            byte[] encrypted = EncriptarStringToBytesAes(original, miAes.Key, miAes.IV);
            return encrypted;
        }

        public string descifrar(byte[] encrypted)
        {
            string roundtrip = DesencriptarStringFromBytesAes(encrypted, miAes.Key, miAes.IV);
            return roundtrip;

        }

        private byte[] EncriptarStringToBytesAes(string cadena, byte[] clave, byte[] IV)
        {

            if (cadena == null || cadena.Length <= 0)
                throw new ArgumentNullException("plainText");

            if (clave == null || clave.Length <= 0)
                throw new ArgumentNullException("Key");

            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");

            byte[] encrypted;

           using (Aes aesAlg = Aes.Create())
           {
                aesAlg.Key = clave;
                aesAlg.IV = IV;
                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);

                using (MemoryStream msEncrypt = new MemoryStream())
                {
                    using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                        {
                            swEncrypt.Write(cadena);

                        }
                        encrypted = msEncrypt.ToArray();
                    }

                }

            }
            return encrypted;
        }

        private string DesencriptarStringFromBytesAes(byte[] textoCifrado, byte[] clave, byte[] IV)
        {
            if (textoCifrado == null || textoCifrado.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (clave == null || clave.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("IV");
            string plaintext = null;

            using (Aes aesAlg = Aes.Create())
            {
                aesAlg.Key = clave;
                aesAlg.IV = IV;

                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
             
                using (MemoryStream msDecrypt = new MemoryStream(textoCifrado))
                {

                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
                        {
                          plaintext = srDecrypt.ReadToEnd();

                        }
                    }

                }
            }
            return plaintext;
        }

    }
}

No hay comentarios:

Publicar un comentario

Curso .NET Core en C# - 34.Creamos nuestro propio log

34.Creamos nuestro propio log Hola a todos. En este curso, analizaremos todos los conceptos básicos, intermedios y avanzados de  ASP.NET...