How to force the user to change his password after first login?
I want to force the user to change his password after his first login. Now, where should I put the redirection开发者_如何学Python code to ChangePassword page ?
- If I put it in the
Page_Load
of Default page, user can move to any page because he is Authenticated. If I put it in the
Page_Load
of Master page, the ChangePassword page uses the same master page, and it'll enter in an infinit loop of redirections.I though of ignoring the redirection if the
Page
is the ChagePassword page from the Master page, and I found this answer which says:This sounds like a bad idea to start with. The idea of the master is that it shouldn't care what page is there as this is all common code for each page.
Any suggestion!
Here you are, a fully tested solution ;)
protected void LoginButton_Click(object sender, EventArgs e)
{
/****note: UserName and Password are textbox fields****/
if (Membership.ValidateUser(UserName.Text, Password.Text))
{
MembershipUser user = Membership.GetUser(UserName.Text);
if (user == null)
{
FailureText.Text = "Invalid username. Please try again.";
return;
}
if (user.IsLockedOut)
user.UnlockUser();
/* this is the interesting part for you */
if (user.LastPasswordChangedDate == user.CreationDate) //if true, that means user never changed their password before
{
//TODO: add your change password logic here
}
}
}
You can do it in GLobal.asax file.
Check if user in logged in and request url is not ChangePassword then redirect to change password page.
/// <summary>
/// this event occurs just after user is authenticated
/// </summary>
void Application_AuthorizeRequest(object sender, EventArgs e)
{
// check if user is authenticated
if (User.Identity.IsAuthenticated)
{
// checking page extension
switch (System.IO.Path.GetExtension(Context.Request.Url.AbsoluteUri.ToLower()))
{
case ".bmp":
case ".gif":
case ".jpg":
case ".jpe":
case ".jpeg":
case ".png":
case ".css":
case ".js":
case ".txt":
case ".swf":
// don't redirect, these requests may required in many cases
break;
default:
// checking if request is not for ChangePassword.aspx page
if (!Context.Request.Url.AbsoluteUri.ToLower().Contains("/changepassword.aspx"))
{
Context.Response.Redirect("~/ChangePassword.aspx");
}
break;
}
}
}
We had an app with similar requirements. We extended the base ASP.NET membership provider to allow for a check on the LastPasswordChangedDate and compared it to the CreateDate. If equal, that means the user has never changed their password, and was redirected to the login page.
I see you would like to have some kind of check to keep bugging them even after the login. I think you can accomplish this in the AuthorizationRequest of the Global.asax. That might be expensive though.
You may handle the following events of the Login control,
•LoggedIn •LoggingIn
Good luck, I hope this helps.
as i understand you should put the validation code in "Page_PreRender"
protected void Page_PreRender(object sender, EventArgs e)
{
//Validation Code
}
this event will fire the code before the page renders anything
Which object are you putting into the section in order to evaluate if the user is authenticated? I would just set a boolean property named "ChangePasswordOnNextLoggin", then if its true I redirect to "ChangePassword.aspx", you may put it wherever you want (even in the master page, as you only redirect if this property is true, avoiding the infinite loop).
But personally I would make a wrapper for the PAGE object, that every .aspx code behind class should inherit, then I would inherit this wrapper instead, on the wrapper ctor I would add an Authenticate method to the Load event in such a way it would be the first method to be called when any page is loaded. If I do it, i'm able to avoid putting validation code on MasterPage and the code behind, making the code cleaner. Do you get it?
In the place of your code where the user is authenticated.
Since you want the user to change his password on the very first login, after registration, you just create one more field in your database's login table which will have a status value whether the initial pasword change process has been done. So when a user logs in the first time, that value is checked and, if it is something like "unchanged," redirect the user from the login page to the change password page. Upon successful password change, update the field.
In SQL Server 2005(plus VS2008), Apart from all the "add one more field" approaches, I think it's much easier to execute asp.net security database's built in stored procedure aspnet_Membership_FindUsersByName
. It returns a dataset with all the info you'll ever need incl last activity date, last password change date, last login date etc with time values.
精彩评论