如何在用户首次登录后强制要求用户更改密码?

10
我想在用户首次登录后强制其更改密码。现在,我应该将重定向代码放在哪个位置以便跳转到ChangePassword页面?
  • 如果我将其放在Default页面的Page_Load中,则用户已通过验证,可以移动到任何页面。
  • 如果我将它放在Master页面的Page_Load中,则ChangePassword页面使用相同的master页面,会进入无限循环的重定向中。
  • 我考虑从Master页面忽略对ChagePassword页面的重定向,并找到了这个答案,上面说:

    这听起来不是一个好主意。毕竟Master的想法是它不关心有什么页面,因为这是每个页面的通用代码。

有什么建议吗?


3
有趣的问题。如果将此功能添加到ASP.NET Web安全模块中会很不错。 - Raptor
1
我想为我的页面创建一个基类(以避免在主控件中执行该操作),并在OnInit中进行以下操作:如果(auth &&!User.HasChangedPassword && typeof(Page)!= typeof(ChangePasswordPage))则Response.Redirect(...(我还没有尝试typeof测试,但您可以测试request.url是否有效))。 - Guillaume86
9个回答

5

这就是您需要的,一个经过全面测试的解决方案 ;)

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
        }
    }
}

2
稍微修改一下以考虑数据库保存时间。var timeSpan = user.LastPasswordChangedDate - user.CreationDate; if (timeSpan.Minutes < 1) - MvcCmsJon
1
这会防止直接访问应用程序资源吗? - Filip
@Filip,不会的,因此仅凭这一点,它本身并不是一个很好的建议 ;) - Andrew Savinykh

1

你可以在 Global.asax 文件中完成。

检查用户是否已登录且请求的 URL 不是 ChangePassword,然后重定向到更改密码页面。

/// <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;
        }
    }
}

如果用户登录后直接访问URL,则此方法将无效。对吗?我们首次登录时进行验证,但他可以自由更改URL并访问页面,而无需真正更改密码? - Brian

1
我们曾经有一个类似的应用程序需求。我们扩展了基础ASP.NET成员资格提供程序,以允许对LastPasswordChangedDate进行检查并将其与CreateDate进行比较。如果相等,则意味着用户从未更改过密码,并被重定向到登录页面。
我看到你想在登录后继续打扰他们。我认为您可以在Global.asax的AuthorizationRequest中实现此操作。不过这可能会很昂贵。

0

据我理解,您应该将验证代码放在“Page_PreRender”中。

protected void Page_PreRender(object sender, EventArgs e)
{
     //Validation Code       
}

这个事件将在页面渲染任何内容之前触发代码


当页面尝试在其生命周期的早期阶段更新数据库或类似操作时失败,会发生什么情况?用户将永远不会知道,因为他们将被发送到“更改密码”页面。 - Jim D'Angelo

0
你把哪个对象放入该部分以评估用户是否经过身份验证?我只会设置一个名为“ChangePasswordOnNextLoggin”的布尔属性,如果为true,则重定向到“ChangePassword.aspx”,您可以将其放在任何地方(甚至主页上),因为只有在此属性为true时才进行重定向,避免无限循环。
但是个人而言,我会为PAGE对象创建一个包装器,每个.aspx代码后台类都应该继承它,然后我将继承此包装器。在包装器的构造函数中,我将添加一个Authenticate方法到Load事件中,以便在任何页面加载时,它是第一个被调用的方法。如果这样做,我就能够避免在MasterPage和代码后台上放置验证代码,使代码更清洁。你明白吗?

0

由于您希望用户在注册后的第一次登录时更改密码,因此只需在数据库的登录表中创建一个额外的字段,该字段将具有状态值,指示初始密码更改过程是否已完成。因此,当用户第一次登录时,将检查该值,并且如果它类似于“未更改”,则将用户从登录页面重定向到更改密码页面。成功更改密码后,请更新该字段。


3
你是在手机上写的这个回答吗? - koan

0
您可以处理登录控件的以下事件:
• LoggedIn • LoggingIn
祝您好运,希望这有所帮助。

问题在于用户已经通过身份验证,因此他可以随意移动。 - Homam
好的,我明白你的意思是如果他在更改密码之前移动,则应将其放在主页面的Page_Load中,并检查Request.Url,如果它不是ChangePassword页面的url,则重定向,从而打破递归。 - A_Nabelsi

0
在用户进行身份验证的代码位置。

-2
在SQL Server 2005(加上VS2008)中,除了所有的“添加一个字段”的方法之外,我认为更容易执行asp.net安全数据库的内置存储过程aspnet_Membership_FindUsersByName。它返回一个数据集,其中包含您所需的所有信息,包括最后活动日期、最后密码更改日期、最后登录日期等时间值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接