I developed a web application. It has a login form using ASP.NET membership. Now I need to add a form allowing to change the password. Before a new password can be set, the old password must be entered by the user.
How can I check if the old password is valid?
// checking if the old password is correct
if (Membership.ValidateUser(username, oldPassword))
{
// setting a new password
string newPassword = MembershipUser.ResetPassword();
}
Membership.ValidateUser
Membership.ResetPassword
if The User logged In then you have the User Id
so retrieve all user Information like user name password using It.
now you Can just ask User to enter his old password now match this two if both matched then change the password with new One.
Use the ChangePassword control.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.changepassword.aspx
Related
To reset a password we need to know a UserId and pass it to the UserManager.ResetPasswordAsync method. In the Identity 1.0 it was possible to obtain UserId from the UserManager.PasswordResetTokens.Validate method ((UserManager.PasswordResetTokens.Validate(token)).UserId). Now it's gone and all existing examples telling me that I need to ask an user for username or email. This is not user friendly, I don't want my users enter username again if token is valid.
This is already established tradition in ASP.NET Identity - something that worked before is broken in the new release. Of course I can create my own combined token with embedded UserId, but why I need to do extra work? New releases should improve things, not make them worse.
Asp.Net Identity 2.x do not provide a way to find a user by a token created from GeneratePasswordResetTokenAsync method.
You have two options:
1) Add the user id at the url you will send to the user. Ex:
var token = await _userManager.GeneratePasswordResetTokenAsync(applicationUser);
var callbackUrl = $"/reset-password/?user={WebUtility.UrlEncode(applicationUser.Id)}&code={WebUtility.UrlEncode(token)}";
This approach is more user friendly. But I know people that says this is a security issue because anyone with the link could reset the user password.
2) Ask for the user name at the reset password page, as you did. Ex:
public async Task<YourResultModel> ResetPassword(ResetPasswordViewModel vm)
{
// Your password validations...
var user = await _userManager.FindByNameAsync(vm.UserName);
// could be FindByEmailAsync if your app uses the user e-mail to login.
IdentityResult result = await _userManager.ResetPasswordAsync(user, vm.Token, vm.NewPassword);
return YourResultModelFromIdentityResult(result);
}
Before choose between this two approaches you need to think about your specific scenario. For example: If your app uses the user e-mail as username and to intercept the token the "interceptor" needs to access the user e-mail box, remove the user id from reset password link will not improve the security of your app. Because who has the link already knows the e-mail of the user.
User is logged in and wants to do something major and I want them to re-enter their password so I can make sure that they are the user that is logged in.
How can I confirm that this password is for the account holder?
Would be happy to know how to do it via ASP.NET Identity or how to set up a stored proc to go against the AspNetUsers table or how to do it via Entity Framework.
How can I confirm that this password is for the account holder?
how to do it via ASP.NET Identity
To reverify the password of currently logged in user, provide the user VerifyView to enter password and use the following method to check if the user exists.
var user = await UserManager.FindAsync(User.Identity.Name,VerifyViewModel.Password)
If the user is found, the current request is the same from the account holder.
Membership.ValidateUser is from earlier version of Membership framework, not from ASP.NET Identity.
You can also use UserManager.CheckPassword() extension function:
UserManagerExtensions.CheckPassword Method
string id = User.Identity.GetUserId();
var user = UserManager.FindById(id);
if(!UserManager.CheckPassword(user, model.Password))
{
ModelState.AddModelError("Password", "Incorrect password.");
}
With Identity framework you never want to hit the database directly. Always use the API provided. The database structure has changed several times in the past few years, so introducing dependencies (e.g. on a data context) is adding work for no reason.
For async usage, see the answer already provided by jd4u.
For synchronously identifying that the password matches the current user, you need to first include:
using Microsoft.AspNet.Identity;
as this brings in a number of synchronous extension methods for identity framework.
You can then check with Find on the UserManager like this:
var user = UserManager.Find(User.Identity.Name, password);
if (user != null)
{
// It is them!
}
If the user is not null, then you have a match of password and current username.
You can use UserManager to do that:
if(UserManager.PasswordHasher.VerifyHashedPassword("hashedPassword", "password")
!= PasswordVerificationResult.Failed)
{
// password is correct
}
For more information see the link:
How to check password manually in Asp.Net identity 2?
I want to update the password without making the user enter his username or emailid as the user will already be logged in.
So in the following code snippet of my webmethod, if i don't wanna use emailid=#emailid at where clause,
where shud i add the code with the logic change password only at the emailid1 and not at emailid 2 if both emailids have same passwords? Thanks.
string update = "update client set pwd=#newpass where pwd=#oldpass";
If the user is already logged in you should have the email in some variable.
And you can use this variable in your updatestring.
So the user dont need to type his email again.
I am using a login control where user enters the username and passwords.I want to retrieve those values of username and password into another page in the application? Is there a way to do that in C#.I am using asp.net login control?
Not the password, as that's double-blind to protect the user's security. But the username is easy to get:
I use this frequently:
lblUser.Text = "Welcome " + User.Identity.Name;
All you have to do is call Membership.GetUser();
How about HttpContext.Current.User?
Excuse my intrusion as I don't know either C# or asp.net. However, you could have a public variable on the system which could hold those info across pages.
I have an ASP.NET App in which want to send an email to a user that presses a Recover Password button that resets the user's password and then sends a link to the user that when followed will log the user in with a new password and bring them to the Change Password page where they must resent their password.
I'm able to reset the password and get the new randomly generated password that I send back to the user in an email. However, when the user follows the link back with the UserName and pw parameters, the system does not seem to log them in,
Here's the code I am using on the load event that does not seem to work:
try
{
string sUserName = Request.QueryString["UserName"].ToString();
string sPw = Request.QueryString["pw"].ToString();
if (Membership.ValidateUser(sUserName, sPw))
{
//Log the user in???
FormsAuthentication.Authenticate(sUserName, sPw);
}
}
catch (Exception r)
{
string sMessage = r.Message;
}
Any help in logging the user in with username and password parameters would be greatly appreciated.
You can use FormsAuthentication.SetAuthCookie() :
if (Membership.ValidateUser(sUserName, sPw))
{
FormsAuthentication.SetAuthCookie(sUserName, true);
}
In your sample code you are retrieving the user name and password from the query string - this is very bad practice as any observer will see it in plain text. At least use a POST for these values and put them in the body (i.e with a form POST) and always use HTTPS at least for your login page.
use the following code.
if (Membership.ValidateUser(sUserName, sPw))
{
FormsAuthentication.SetAuthCookie(sUserName, true);
Response.Redirect("ChangePassword.aspx");
}
FormsAuthentication.Authenticate is almost same as FormsAuthentication.ValidateUser. They just validate user authentication. SetAuthCookie creates the authentication ticket(login).
This is how (IMO) reset password functionality should work:
User clicks button saying "Forgot Password".
In your code store a random GUID in the DB.
Send the user an email, with the GUID as a link in the email, as well as their userid, e.g:
http://yoursite.com/user/reset?guid=a21312738&userid=213123
On the incoming page, read the userid from the QS, and fetch the user from the DB by this value.
Compare the stored GUID from the GUID in the QS. If success, render a form that allows the user to change the password via an HTTPS POST.
In the POST action, change the user's password and sign them in.
You could also go one step further and store an expiration date for the GUID (e.g user must change their password in 24 hours).