问题
I have a new table that hold old passwords, I need to check if there is a match.
If there is a match I need the ChangePassword contol to NOT change the password. I need to tell the user that this password was used and pic a new one.
I can't seem to be able to interrupt the control from changing the password. Maybe I am using the wrong event.
Here is a piece of my code, or how I wish it would work. I appreciate all your help.
protected void ChangePassword1_ChangedPassword(object sender, EventArgs e)
{
MembershipUser user = Membership.GetUser();
string usrName = "";
if (user != null)
{
string connStr = ConfigurationManager.ConnectionStrings["LocalSqlServer"].ConnectionString;
SqlConnection mySqlConnection = new SqlConnection(connStr);
SqlCommand mySqlCommand = mySqlConnection.CreateCommand();
mySqlCommand.CommandText = "Select UserName from OldPasswords where UserName = 'test'";
mySqlConnection.Open();
SqlDataReader mySqlDataReader = mySqlCommand.ExecuteReader(CommandBehavior.Default);
while (mySqlDataReader.Read())
{
usrName = mySqlDataReader["UserName"].ToString();
if (usrName == user.ToString())
{
Label1.Text = "Match";
}
else
{
Label1.Text = "NO Match!";
}
}
回答1:
You are overriding the wrong method, Steve. You want to override the cancellable ChangingPassword
.
Try this:
protected void ChangePassword1_ChangingPassword(object sender, LoginCancelEventArgs e)
{
// do your lookup here,
bool passwordHasBeenPreviouslyUsed = true;
if (passwordHasBeenPreviouslyUsed)
{
e.Cancel = true;
// notify of error
return;
}
}
And, as per previous Q/A sessions, You should NEVER EVER EVER store a user's password1. Go to the membership table and get the salt and use that to hash the incoming password to compare to the already salt-hashed values you have stored in your lookup table.
Good luck.
(1) - how tenable would your position be when the CEO finds out that his password has been stored in an exploitable format? There is a level of trust given to the black mages that are us and that trust carries it's own risks. Be aware of them. ;-)
EDIT:
A working example:
ChangePassword.aspx
<%@ Page Language="C#" %>
<%@ Import Namespace="System.Diagnostics"%>
<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
}
protected void ChangePassword1_ChangingPassword(object sender, LoginCancelEventArgs e)
{
// works for me!
Debugger.Break();
}
</script>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ChangePassword ID="ChangePassword1" runat="server" OnChangingPassword="ChangePassword1_ChangingPassword">
</asp:ChangePassword>
</div>
</form>
</body>
</html>
Update: You may also be interested in simply defining a handler in a higher scope that will watch all password activity:
consider this
public void SetupPasswordActionHook()
{
//Occurs when a user is created, a password is changed, or a password is reset.
Membership.ValidatingPassword += Membership_ValidatingPassword;
}
void Membership_ValidatingPassword(object sender, ValidatePasswordEventArgs e)
{
// Gets a value that indicates whether the System.Web.Security.MembershipProvider.ValidatingPassword event is being raised during a
// call to the System.Web.Security.MembershipProvider.CreateUser() method.
// true if the System.Web.Security.MembershipProvider.ValidatingPassword event is being raised during a call to the
// System.Web.Security.MembershipProvider.CreateUser() method; otherwise, false.
bool isNewUser = e.IsNewUser;
// Gets the password for the current create-user, change-password, or reset-password action.
// The password for the current create-user, change-password, or reset-password action.
string password = e.Password;
// Gets the name of the membership user for the current create-user, change-password, or reset-password action.
// The name of the membership user for the current create-user, change-password, or reset-password action.
string username = e.UserName;
// Gets or sets a value that indicates whether the current create-user, change-password, or reset-password action will be canceled.
// true if the current create-user, change-password, or reset-password action will be canceled; otherwise, false. The default is false.
e.Cancel = true;
// Gets or sets an exception that describes the reason for the password-validation failure.
// An System.Exception that describes the reason for the password-validation failure.
e.FailureInformation = new Exception("This is why I failed your password");
}
来源:https://stackoverflow.com/questions/2721382/asp-net-membership-changepassword-control-need-to-check-for-previous-password