Get password from a user with UserManager - c#

I'm making a website with MVC5 ASP.NET.
I'm using Identity framework 2.0 implement class with properties such as passwordhash, username, email, emailconfirmed and so on. I'm using userManager.ChangePassword(user.Id, Oldpassword, Newpassword);, but i can't figure out how i should get a password from a user as plain text (string)
[HttpPost]
public ActionResult ChangePassword(AspNetUsersViewModel userView)
{
UserManager<IdentityUser> userManager = new UserManager<IdentityUser>(new UserStore<IdentityUser>());
var result = userManager.ChangePassword(_User.Id, "123456789", userView.Password);
return RedirectToAction("Index", "ConfigUser");
}
As now I'm i have hardcoded users current password "123456789" to test if it works, and it does.
I hope you guys can help.

Add password input to the View inside the form tag
<input type="password" id= "userNewPassword" name="userNewPassword">
Pass the userNewPasswor as string to the controller after the userView and the pass it to the UserManager
[HttpPost]
public ActionResult ChangePassword(
AspNetUsersViewModel userView,
string userNewPassword){
UserManager<IdentityUser> userManager = new UserManager<IdentityUser>(new UserStore<IdentityUser>());
var result = userManager.ChangePassword(_User.Id, userNewPassword , userView.Password);
return RedirectToAction("Index", "ConfigUser");
}
Note: the Best way is to Modify the userView and add the userNewPassword to the model
Update:
in the visual studio 2013 the if you used the asp.net default template you will find the flowing class
public class ChangePasswordBindingModel
{
[Required]
[DataType(DataType.Password)]
[Display(Name = "Current password")]
public string OldPassword { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "New password")]
public string NewPassword { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm new password")]
[Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}

Related

Adding a dropdown of Roles in the built-in Register.cshtml view and retrieving its selected value in the Reginster action method

I've an ASP.NET Core app with Individual User Accounts authentication. The app by default creates AccountController, RegisterViewModel, Register.cshtml etc as shown below. I've added two properties for a Role dropdown in the RegisterViewModel and I'm displaying that dropdown in the Register.cshtml view so an admin can select a role for a newly created user.
Question: In the following Post method for Register, how do I retrieve the role admin selected from the Register.cshtml view? In other words, in this Post action method how do I use that selected role so I can add the newly created user to that role?
RegisterViewModel:
public class RegisterViewModel
{
[Required]
[Display(Name = "Login")]
public string UserName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Display(Name = "Select Role")]
public ApplicationRole SelectedRole { get; set; }
public IEnumerable<SelectListItem> Roles { get; set; }
}
AccountController Action Method:
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Register(RegisterViewModel model, string returnUrl = null)
{
ViewData["ReturnUrl"] = returnUrl;
if (ModelState.IsValid)
{
var user = new ApplicationUser { UserName = model.UserName, StateID=model.StateID, Region=model.Region };
var result = await _userManager.CreateAsync(user, model.Password);
if (result.Succeeded)
{
await _signInManager.SignInAsync(user, isPersistent: false);
_logger.LogInformation(3, "User created a new account with password.");
return RedirectToLocal(returnUrl);
}
AddErrors(result);
}
// If we got this far, something failed, redisplay form
return View(model);
}
to your view model add a selected parameter
[Display(Name = "Selected Role")]
public int SelectedRole{ get; set; }
then on your view setup the drop down like this
#Html.DropDownListFor(x => x.SelectedRole, model.Roles)
this will tie the result of the drop down to your model. then on your controller model.SelectedRole should have your selected id

How can I send a Confirmation Email in asp.net mvc

Today i'm trying to follow this article of Shai Raiten's Blog and when I finish it the createStatus return invalidAnswer
here is my Register action
[HttpPost]
[AllowAnonymous]
[CaptchaValidation("CaptchaCode", "registerCaptcha", "Wrong captcha!")]
public ActionResult Register(RegisterModel model)
{
if (ModelState.IsValid)
{
MembershipCreateStatus createStatus;
Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, false, null, out createStatus);
if (createStatus == MembershipCreateStatus.Success)
{
MailHelper.SendConfirmationEmail(model.UserName);
return RedirectToAction("Confirmation", "User");
}
else
{
ModelState.AddModelError("", "Failed!");
}
}
return View(model);
}
and here is my RegisterModel.cs
public class RegisterModel
{
[Key]
public long ID { set; get; }
[Required(ErrorMessage = "Do not Skip this")]
public string UserName { set; get; }
[StringLength(500, MinimumLength = 6, ErrorMessage = "Atleast 6 characters in passwords")]
[Required(ErrorMessage = "Do not Skip this")]
public string Password { set; get; }
[Compare("Password", ErrorMessage = "Wrong confirm passwords")]
[Required(ErrorMessage = "Do not skip this")]
public string ConfirmPassword { set; get; }
public string Name { set; get; }
public string Address { set; get; }
[RegularExpression(#"\A(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*#(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)\Z", ErrorMessage = "This is not an email")]
public string Email { set; get; }
public string Phone { set; get; }
public bool EmailConfirm { set; get; }
}
any suggestion for me , really appreciated all the help you guys make.
The simplest thing you can do is:
First, you should define a property in your user model which will hold email confirmation token. Also, you should define property bool IsEmailConfirmed which defaults to false.
The token should be something like auto-generated random string. E.g. Guid.NewGuid().ToString()
Then, you should define another action, say [HttpGet, AllowAnonymous] ConfirmEmail(string email, string token), which will validate that token against saved in the database and update IsEmailConfirmed accordingly.
And the link you are asking about, should then point to an url which will look like something like that: http://YOUR.SERVER/YourController/ConfirmEmail?email={0}&token={1}, where {0} is user email and {1} is your user email confirmation token. It should return a view that tells whether confirmation was successfull.
However, i do recommend not to reinvent the wheel and to simply use Asp.Net Identity 2.0 framework, which will do all that authn & authz stuff for you.
Please follow the below example from ASP.Net site where its beautifully explained how to send email during registration prcoess.
http://www.asp.net/mvc/overview/security/create-an-aspnet-mvc-5-web-app-with-email-confirmation-and-password-reset
Additionally I would not recommend MD5 password hashinh since its pretty old, try using SHA 256 hashing for password encryption.
http://forums.asp.net/t/1211478.aspx?How+do+I+use+Sha256+to+Encrypt+a+String+

Setting up password/confirm password without [Compare]

I am using Asp.net MVC to create a password and confirm password field. I am currently using the remote attribute to check if password and confirm password are the same, however remote will only call a function if the box it is applied to is changed.
I've looked through previous posts going back to last year and found the most common suggestion to be the compare attribute, however it is now deprecated.
I assume there is a pre-built solution for this problem.
This is from the model
[Remote(UserController.ActionNameConstants.PasswordMatch,
UserController.NameConst, AdditionalFields = "ConfirmPassword",
ErrorMessage = "The passwords do not match")]
[MinLength(8, ErrorMessage="Minimum password length is 8")]
[DisplayName("Password"), RequiredIf("Id == 0",
ErrorMessage="Password is required")]
public string Password { get; set; }
[DisplayName("Confirm Password"), RequiredIf("Id == 0",
ErrorMessage = "Confirm password is required")]
public string ConfirmPassword { get; set; }
This is in the controller
[HttpGet]
public virtual JsonResult PasswordMatch(string password,string confirmPassword)
{
return this.Json(password ==
confirmPassword,JsonRequestBehavior.AllowGet);
}
Compare is not depricate you can still use [Compare("Property name to compare with")]... it's in "System.ComponentModel.DataAnnotations" namespace.

No validation other than Required working for my test method

I am creating a test method in Asp.Net MVC 5. I am using following code to test my registration method
[TestMethod]
public async Task Registration_Test_For_Password_And_Confirm_Password_Mismatch()
{
// Arrange
var registerationModel = new RegisterViewModel() { UserName = "abc", Password = null, ConfirmPassword = "jjk", Email = "nitin.daiya#sunarctechnologies.com" };
// Validate model state start
var validationContext = new ValidationContext(registerationModel, null, null);
Validator.TryValidateObject(registerationModel, validationContext, validationResults);
foreach (var validationResult in validationResults)
{
controller.ModelState.AddModelError(validationResult.MemberNames.First(), validationResult.ErrorMessage);
}
// Validate model state end
// Act
var result = await controller.Register(registerationModel) as ViewResult;
// Assert
Assert.AreEqual("", result.ViewName);
Assert.IsFalse(controller.ModelState.IsValid);
}
Above code is working fine if I pass empty values for the Required fields.
If I try to check any other validation it is not showing the error message and test fails each time.
Following is my ViewModel
public class RegisterViewModel
{
public string UserId { get; set; }
[Required]
[System.Web.Mvc.Remote("IsUserNameAvailable", "Account", ErrorMessage = "That UserName is already taken.")]
[Display(Name = "User Name")]
public string UserName { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm Password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Required]
[EmailAddress]
[System.Web.Mvc.Remote("IsEmailAvailable", "Account", ErrorMessage = "That email is already taken.")]
[Display(Name = "Email")]
public string Email { get; set; }
}
Any help will be appreciated
EDIT: Solved the issue by changing Validator.TryValidateObject(registerationModel, validationContext, validationResults); to Validator.TryValidateObject(registerationModel, validationContext, validationResults,true); this. True is set for validateAllProperties property to check all validation.
It still not testing the remote validation. Any clue??
Validator.TryValidateObject(registerationModel, validationContext, validationResults)
This line will by default only validate required properties. To validate all properties, you need to set the validateAllProperties parameter to true:
Validator.TryValidateObject(registerationModel, validationContext, validationResults, true);
(Adding this as it wasn't immediately clear that this question had an answer)

Web API Individual Accounts: how add Roles

in ASP Web API i use the individual accounts to register the user. I have implemented this functionality following this official tutorial:
Web API Individual Accounts
Now i want be able to assign a Role to the user: when is executed the Register method i want pass also the role in the POST request:
{
"UserName": "Alice",
"Password": "password123",
"ConfirmPassword": "password123",
"Role": "admin" -> i want add this
}
and the Register method must value the database's table properly.
How can i handle the roles in the web api individual accounts? There's any tutorial?
Thanks
Just add the following line in your code after you have created the user and the appropriate role
var roleresult = UserManager.AddToRole(currentUser.Id, "RoleName");
You should also add the Role property to your view model (it is normally called RegisterBindingModel) which is passed to the Register method.
Update
Here's a complete example how a Register method could look like (RoleEntity and UserEntity are my implementations of the appropriate classes in Identity, but this will also work with your custom implementation)
public async Task<IdentityResult> RegisterAsync(RegisterViewModel model)
{
var user = new UserEntity { UserName = model.UserName };
var role = model.Role.ToString();
if (await _roleManager.FindByNameAsync(role) == null)
{
var roleResult = await _roleManager.CreateAsync(new RoleEntity(role));
if (roleResult != IdentityResult.Success)
{
return roleResult;
}
}
var result = await _userManager.CreateAsync(user, model.Password);
if (!result.Succeeded)
{
return result;
}
var addToRoleResult = await _userManager.AddToRoleAsync(user.Id, role);
return !addToRoleResult.Succeeded ? addToRoleResult : IdentityResult.Success;
}
My RegisterViewModel looks something like this
public class RegisterViewModel
{
[Required(ErrorMessage="This field is required")]
[Display(Name = "User name", Prompt="Please enter user name...")]
public string UserName { get; set; }
[Required(ErrorMessage = "This field is required")]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password", Prompt="Please enter password...")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password", Prompt = "Please enter confirm password...")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
[Required(ErrorMessage = "This field is required")]
[Display(Name = "Role")]
public Roles Role { get; set; }
}

Categories