with password net mvc hacer google example como asp and asp.net-mvc mono password-recovery

asp.net-mvc - password - oauth2 asp net mvc



Dónde encontrar el código de muestra de C#para implementar la recuperación de contraseña en ASP.NET MVC2 (5)

¿Cómo implementar restablecimiento de contraseña en la aplicación MVC2?

Las contraseñas se procesan usando el proveedor de membresía ASP .NET. La pregunta de recuperación de contraseña no se usa. Se utiliza una plantilla de proyecto ASP.NET MVC2 estándar con clase AccountController estándar.

Si el usuario pierde la contraseña, el correo electrónico con un enlace temporal o con una nueva contraseña debe enviarse a la dirección de correo electrónico del usuario.

¿Dónde encontrar el código para implementar esto en MVC 2 C #?

El desbordamiento de la pila contiene dos respuestas que discuten los métodos para implementar esto. No hay código de muestra. Busqué en Google para "asp .net mvc contraseña restablecer c # código de muestra descarga" pero no he encontrado el código de muestra para esto.

Soy nuevo en MVC. Dónde encontrar el código de muestra para la recuperación de contraseña? Esto falta en la plantilla del proyecto generado por VS2010.

Actualizar

Intenté este código en Mono 2.10 pero obtuve una excepción:

CspParameters no admitidos por Mono

en línea

des.Key = pdb.CryptDeriveKey("RC2", "MD5", 128, new byte[8]);

¿Cómo se ejecuta en Mono?

Stack Trace:

System.NotSupportedException: CspParameters not supported by Mono at System.Security.Cryptography.PasswordDeriveBytes.CryptDeriveKey (string,string,int,byte[]) [0x0001b] in /usr/src/redhat/BUILD/mono-2.10.2/mcs/class/corlib/System.Security.Cryptography/PasswordDeriveBytes.cs:197 at store2.Helpers.Password.EncodeMessageWithPassword (string,string) <IL 0x00055, 0x000f3> at store2.Helpers.AccountHelper.GetTokenForValidation (string) <IL 0x00033, 0x00089> at MvcMusicStore.Controllers.AccountController.PasswordReminder (MvcMusicStore.Models.PasswordReminderModel) <IL 0x001ac, 0x00495> at (wrapper dynamic-method) System.Runtime.CompilerServices.ExecutionScope.lambda_method (System.Runtime.CompilerServices.ExecutionScope,System.Web.Mvc.ControllerBase,object[]) <IL 0x00020, 0x0005b> at System.Web.Mvc.ActionMethodDispatcher.Execute (System.Web.Mvc.ControllerBase,object[]) <IL 0x00008, 0x0001b> at System.Web.Mvc.ReflectedActionDescriptor.Execute (System.Web.Mvc.ControllerContext,System.Collections.Generic.IDictionary`2<string, object>) <IL 0x00072, 0x00103> at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod (System.Web.Mvc.ControllerContext,System.Web.Mvc.ActionDescriptor,System.Collections.Generic.IDictionary`2<string, object>) <IL 0x00003, 0x00019> at System.Web.Mvc.ControllerActionInvoker/<>c__DisplayClassd.<InvokeActionMethodWithFilters>b__a () <IL 0x0002d, 0x00068> at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter (System.Web.Mvc.IActionFilter,System.Web.Mvc.ActionExecutingContext,System.Func`1<System.Web.Mvc.ActionExecutedContext>) <IL 0x00031, 0x000b6> -------------------------------------------------------------------------------- Version information: Mono Runtime Version: 2.10.2 (tarball Mon Apr 18 18:57:39 UTC 2011); ASP.NET Version: 2.0.50727.1433


Tengo un ejemplo de cómo implementar la recuperación de contraseñas en una aplicación ASP.NET MVC estándar en mi blog.

Esta publicación de blog asume que ya tiene el proceso de inicio de sesión funcionando (base de datos y todo) y que solo necesita cablear el proceso de recuperación de contraseña.

http://hectorcorrea.com/Blog/Password-Recovery-in-an-ASP.NET-MVC-Project


Establezca un GUID de restablecimiento de contraseña en la tabla de usuario. También puede usar un tiempo de vencimiento. Si el usuario intentó restablecer la contraseña, actualice el campo con un nuevo GUID y fecha de vencimiento.

Envíe un enlace que contenga el enlace para restablecer la contraseña con el GUID.

Se puede crear una función de muestra como esta para ese

GUID res = objPasswordResetService.resetPassword(Convert.ToInt64(objUserViewModel.UserID), restpasswordGuid, resetPasswordExpiryDateTime);

El valor en res puede ser el GUID actualizado en DB. Envíe un enlace con este GUID. También puede verificar el tiempo de vencimiento. Esto es solo una idea


Respuesta para implementar restablecimiento de contraseña en la aplicación MVC2

public string ResetPassword(string userName) { MembershipUser user = _provider.GetUser(userName, false); if (user.IsLockedOut) user.UnlockUser(); user.Comment = null; _provider.UpdateUser(user); string newPassword = user.ResetPassword(); string friendlyPassword = GenerateNewPassword(); _provider.ChangePassword(userName, newPassword, friendlyPassword); return friendlyPassword; } private string GenerateNewPassword() { string strPwdchar = "abcdefghijklmnopqrstuvwxyz0123456789#@$ABCDEFGHIJKLMNOPQRSTUVWXYZ"; string strPwd = ""; Random rnd = new Random(); for (int i = 0; i <= 8; i++) { int iRandom = rnd.Next(0, strPwdchar.Length - 1); strPwd += strPwdchar.Substring(iRandom, 1); } return strPwd; }


Aquí está mi enfoque. En MVC tendrá una acción llamada RetrievePassword donde le pedirá la dirección de correo electrónico del usuario y la pasará en una publicación.

[HttpGet] public ActionResult RetrievePassword() { return View(); } [HttpPost] public ActionResult RetrievePassword(PasswordRetrievalModel model) { if (ModelState.IsValid) { string username = Membership.GetUserNameByEmail(model.Email); if (!String.IsNullOrEmpty(username)) { // This is a helper function that sends an email with a token (an MD5). NotificationsHelper.SendPasswordRetrieval(model.Email, this.ControllerContext); } else { Trace.WriteLine(String.Format("*** WARNING: A user tried to retrieve their password but the email address used ''{0}'' does not exist in the database.", model.Email)); } return RedirectToAction("Index", "Home"); } return View(model); }

Se enviará un mensaje de correo electrónico con una URL que redirige a http://example.com/Account/Validate?email=xxxxxxxx&token=xxxxxxxx

Si el token es válido para el correo electrónico, probablemente mostrarás un formulario de restablecimiento de contraseña para que elijan una nueva contraseña.

Entonces necesitas una acción de validación:

[HttpGet] [CompressFilter] public ActionResult Validate(string email, string token) { bool isValid = false; if (AccountHelper.IsTokenValid(token, email)) { string username = Membership.GetUserNameByEmail(email); if (!String.IsNullOrEmpty(username)) { // Get the user and approve it. MembershipUser user = Membership.GetUser(username); user.IsApproved = true; Membership.UpdateUser(user); isValid = true; // Since it was a successful validation, authenticate the user. FormsAuthentication.SetAuthCookie(username, false); } else { isValid = false; } } return View(isValid); }

Estos son algunos de los ayudantes que ves en este código:

Ayudante de cuenta

/// <summary> /// Gets the token for invitation. /// </summary> /// <param name="email">The email.</param> /// <returns></returns> public static string GetTokenForInvitation(string email) { if (String.IsNullOrEmpty(email)) throw new ArgumentException("The email cannot be null"); string token = Password.EncodeMessageWithPassword(String.Format("{0}#{1}", email, DateTime.Now), SEED); return token; } /// <summary> /// Gets the email from token. /// </summary> /// <param name="token">The token.</param> /// <param name="email">The email.</param> /// <returns></returns> public static bool GetEmailFromToken(string token, out string email) { email = String.Empty; string message = Password.DecodeMessageWithPassword(token, SEED); string[] messageParts = message.Split(''#''); if (messageParts.Count() != 2) { return false; // the token was not generated correctly. } else { email = messageParts[0]; return true; } } /// <summary> /// Helper function used to generate a token to be used in the message sent to users when registered the first time to confirm their email address. /// </summary> /// <param name="email">The email address to encode.</param> /// <returns>The token generated from the email address, timestamp, and SEED value.</returns> public static string GetTokenForValidation(string email) { if (String.IsNullOrEmpty(email)) throw new ArgumentException("The email cannot be null"); string token = Password.EncodeMessageWithPassword(String.Format("{0}#{1}", email, DateTime.Now), SEED); return token; } /// <summary> /// Validates whether a given token is valid for a determined email address. /// </summary> /// <param name="token">The token to validate.</param> /// <param name="email">The email address to use in the validation.</param> /// <returns><c>true</c> if the token is valid, <c>false</c> otherwise.</returns> public static bool IsTokenValid(string token, string email) { return IsTokenValid(token, email, DateTime.Now); } /// <summary> /// Core method to validate a token that also offers a timestamp for testing. In production mode should always be DateTime.Now. /// </summary> /// <param name="token">The token to validate.</param> /// <param name="email">the email address to use in the validation.</param> /// <param name="timestamp">The timestamp representing the time in which the validation is performed.</param> /// <returns><c>true</c> if the token is valid, <c>false</c> otherwise.</returns> public static bool IsTokenValid(string token, string email, DateTime timestamp) { if (String.IsNullOrEmpty(token)) throw new ArgumentException("The token cannot be null"); try { string message = Password.DecodeMessageWithPassword(token, SEED); string[] messageParts = message.Split(''#''); if (messageParts.Count() != 2) { return false; // the token was not generated correctly. } else { string messageEmail = messageParts[0]; string messageDate = messageParts[1]; // If the emails are the same and the date in which the token was created is no longer than 5 days, then it is valid. Otherwise, it is not. return (String.Compare(email, messageEmail, true) == 0 && timestamp.Subtract(DateTime.Parse(messageDate)).Days < 5); } } catch (Exception) { // could not decrypt the message. The token has been tampered with. return false; } }

Y finalmente aquí un código para cifrar, decript token ...

Lo tengo en una clase de Contraseña que está destinada a ser un ayudante.

/// EDIT: eliminó las dos funciones a las que hice referencia anteriormente y muestra la clase de ayuda completa.

Aquí está la clase Password static con todas las funciones auxiliares.

using System; using System.Text; using System.IO; using System.Security.Cryptography; using System.Data; using System.Resources; namespace MySolution.Common.Util { /// <summary> /// Implements some functions to support password manipulation or generation /// </summary> public class Password { /// <summary> /// Takes a string and generates a hash value of 16 bytes. /// </summary> /// <param name="str">The string to be hashed</param> /// <param name="passwordFormat">Selects the hashing algorithm used. Accepted values are "sha1" and "md5".</param> /// <returns>A hex string of the hashed password.</returns> public static string EncodeString(string str, string passwordFormat) { if (str == null) return null; ASCIIEncoding AE = new ASCIIEncoding(); byte[] result; switch (passwordFormat) { case "sha1": SHA1 sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider(); result = sha1.ComputeHash(AE.GetBytes(str)); break; case "md5": MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); result = md5.ComputeHash(AE.GetBytes(str)); break; default: throw new ArgumentException("Invalid format value. Accepted values are ''sha1'' and ''md5''.", "passwordFormat"); } // Loop through each byte of the hashed data // and format each one as a hexadecimal string. StringBuilder sb = new StringBuilder(16); for (int i = 0; i < result.Length; i++) { sb.Append(result[i].ToString("x2")); } return sb.ToString(); } /// <summary> /// Takes a string and generates a hash value of 16 bytes. Uses "md5" by default. /// </summary> /// <param name="str">The string to be hashed</param> /// <returns>A hex string of the hashed password.</returns> public static string EncodeString(string str) { return EncodeString(str, "md5"); } /// <summary> /// Takes a string and generates a hash value of 16 bytes. /// </summary> /// <param name="str">The string to be hashed</param> /// <param name="passwordFormat">Selects the hashing algorithm used. Accepted values are "sha1" and "md5".</param> /// <returns>A string of the hashed password.</returns> public static string EncodeBinary(byte[] buffer, string passwordFormat) { if (buffer == null) return null; byte[] result; switch (passwordFormat) { case "sha1": SHA1 sha1 = new System.Security.Cryptography.SHA1CryptoServiceProvider(); result = sha1.ComputeHash(buffer); break; case "md5": MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider(); result = md5.ComputeHash(buffer); break; default: throw new ArgumentException("Invalid format value. Accepted values are ''sha1'' and ''md5''.", "passwordFormat"); } // Loop through each byte of the hashed data // and format each one as a hexadecimal string. StringBuilder sb = new StringBuilder(16); for (int i = 0; i < result.Length; i++) { sb.Append(result[i].ToString("x2")); } return sb.ToString(); } /// <summary> /// Encodes the buffer using the default cryptographic provider. /// </summary> /// <param name="buffer">The buffer.</param> /// <returns></returns> public static string EncodeBinary(byte[] buffer) { return EncodeBinary(buffer, "md5"); } /// <summary> /// Creates a random alphanumeric password. /// </summary> /// <returns>A default length character string with the new password.</returns> /// <remarks>The default length of the password is eight (8) characters.</remarks> public static string CreateRandomPassword() { //Default length is 8 characters return CreateRandomPassword(8); } /// <summary> /// Creates a random alphanumeric password on dimension (Length). /// </summary> /// <param name="Length">The number of characters in the password</param> /// <returns>The generated password</returns> public static string CreateRandomPassword(int Length) { Random rnd = new Random(Convert.ToInt32(DateTime.Now.Millisecond)); //Creates the seed from the time string Password=""; while (Password.Length < Length ) { char newChar = Convert.ToChar((int)((122 - 48 + 1) * rnd.NextDouble() + 48)); if ((((int) newChar) >= ((int) ''A'')) & (((int) newChar) <= ((int) ''Z'')) | (((int) newChar) >= ((int) ''a'')) & (((int) newChar) <= ((int) ''z'')) | (((int) newChar) >= ((int) ''0'')) & (((int) newChar) <= ((int) ''9''))) Password += newChar; } return Password; } /// <summary> /// Takes a text message and encrypts it using a password as a key. /// </summary> /// <param name="plainMessage">A text to encrypt.</param> /// <param name="password">The password to encrypt the message with.</param> /// <returns>Encrypted string.</returns> /// <remarks>This method uses TripleDES symmmectric encryption.</remarks> public static string EncodeMessageWithPassword(string plainMessage, string password) { if (plainMessage == null) throw new ArgumentNullException("encryptedMessage", "The message cannot be null"); TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider(); des.IV = new byte[8]; //Creates the key based on the password and stores it in a byte array. PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, new byte[0]); des.Key = pdb.CryptDeriveKey("RC2", "MD5", 128, new byte[8]); MemoryStream ms = new MemoryStream(plainMessage.Length * 2); CryptoStream encStream = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write); byte[] plainBytes = Encoding.UTF8.GetBytes(plainMessage); encStream.Write(plainBytes, 0, plainBytes.Length); encStream.FlushFinalBlock(); byte[] encryptedBytes = new byte[ms.Length]; ms.Position = 0; ms.Read(encryptedBytes, 0, (int)ms.Length); encStream.Close(); return Convert.ToBase64String(encryptedBytes); } /// <summary> /// Takes an encrypted message using TripleDES and a password as a key and converts it to the original text message. /// </summary> /// <param name="encryptedMessage">The encrypted message to decode.</param> /// <param name="password">The password to decode the message.</param> /// <returns>The Decrypted message</returns> /// <remarks>This method uses TripleDES symmmectric encryption.</remarks> public static string DecodeMessageWithPassword(string encryptedMessage, string password) { if (encryptedMessage == null) throw new ArgumentNullException("encryptedMessage", "The encrypted message cannot be null"); TripleDESCryptoServiceProvider des = new TripleDESCryptoServiceProvider(); des.IV = new byte[8]; //Creates the key based on the password and stores it in a byte array. PasswordDeriveBytes pdb = new PasswordDeriveBytes(password, new byte[0]); des.Key = pdb.CryptDeriveKey("RC2", "MD5", 128, new byte[8]); //This line protects the + signs that get replaced by spaces when the parameter is not urlencoded when sent. encryptedMessage = encryptedMessage.Replace(" ", "+"); MemoryStream ms = new MemoryStream(encryptedMessage.Length * 2); CryptoStream decStream = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write); byte[] plainBytes; try { byte[] encBytes = Convert.FromBase64String(Convert.ToString(encryptedMessage)); decStream.Write(encBytes, 0, encBytes.Length); decStream.FlushFinalBlock(); plainBytes = new byte[ms.Length]; ms.Position = 0; ms.Read(plainBytes, 0, (int)ms.Length); decStream.Close(); } catch(CryptographicException e) { throw new ApplicationException("Cannot decrypt message. Possibly, the password is wrong", e); } return Encoding.UTF8.GetString(plainBytes); } } }