2008-12-08 129 views
21

我正在使用ASP.NET成员身份验证我的Web应用程序。这对我很好。我现在必须实现密码过期。ASP.NET会员密码到期

如果密码已过期,用户应该被重定向到ChangePassword屏幕,并且不应该允许在不更改密码的情况下访问应用程序的任何其他部分。

有许多aspx页面。如果密码已过期,一种解决方案可能是重定向到每个aspx的ChangePassword屏幕OnInit。有没有其他的解决方案或建议。

感谢, 洁

回答

13

您可以添加的事件处理程序在Global.asax中HttpApplication.PostAuthenticateRequest事件和处理重定向那里。

+6

这就是我会做的,结合使用成员资格提供者的LastPasswordChangedDate属性来确定何时到期。 – technophile 2008-12-08 14:45:04

6

刚刚在大约一个小时内实现了这一点,无需修改您的基本页面。继承人你必须做的事情:

  1. 回应了LoggingIn事件成员控制

  2. 的查找会员数据库的用户即可获得LastPasswordChangedDate

  3. 使用时间跨度,比较这与当前日期并决定密码的最后更改是否超过了前几天的必要数量。我得到的web.config

  4. 如果过期这个值,重定向到ChangePassword屏幕

+1

这不会吸引拥有现有身份验证票证的用户(“记住我”)。 csgero的解决方案是正确的。 – Brett 2011-05-19 17:42:59

+0

是的,如果他们目前已被认证,我会说这不是一个大问题,除非你让你的cookies有效到无穷远。也许,如果您检测到它们已经登录并过期,那么只需将cookie设置为每次20分钟左右即可过期。然后,当他们回来时,他们将不得不改变它。 – 2011-08-18 05:15:44

+1

PostAuth中的检查问题也是每个请求增加了大量系统活动。只要您的票证经常过期,应该没有太大问题,或者您只需在超时时间后运行PostAuth代码+1天即可。这可以确保任何使用有效表单身份验证票打入网站的人都会被检查。那么如果他们在这段时间内没有登录,表单验证票即将过期,甚至可以使用LogginIn。在票证过期后超过+1天后,您可以删除PostAuth事件。您还需要登录 – 2012-01-24 21:46:01

26

csgero's answer,我发现你并不需要显式地添加事件处理此事件中ASP.Net 2.0(3.5)。

您可以简单地创建global.asax下面的方法,它被有线为你:

void Application_PostAuthenticateRequest(object sender, EventArgs e) 
{ 
    if (this.User.Identity.IsAuthenticated) 
    { 
     // get user 
     MembershipUser user = Membership.GetUser(); 

     // has their password expired? 
     if (user != null 
      && user.LastPasswordChangedDate.Date.AddDays(90) < DateTime.Now.Date 
      && !Request.Path.EndsWith("/Account/ChangePassword.aspx")) 
     { 
      Server.Transfer("~/ChangePassword.aspx"); 
     } 
    } 
} 
9

Andrew's answer,我发现你需要检查该用户是不是已经更改密码页面上,否则他们将永远无法真正改变他们的密码,因此不会离开更改密码的网站:

void Application_PostAuthenticateRequest(object sender, EventArgs e) 
    { 
     if (this.User.Identity.IsAuthenticated) 
     { 
      // get user 
      MembershipUser user = Membership.GetUser(); 

      // has their password expired? 
      if (user != null 
       && user.LastPasswordChangedDate.AddMinutes(30) < DateTime.Now 
       && !Request.Path.EndsWith("/Account/ChangePassword.aspx")) 
      { 
       Server.Transfer("~/Account/ChangePassword.aspx"); 
      } 
     } 
    } 
4

我来到这里寻找解决这一点,但我目前的技术是ASP.NET MVC。因此,为了帮助别人:你可以扩展AuthorizeAttribute,并覆盖OnAuthorization方法,像这样:

public class ExpiredPasswordAttribute : AuthorizeAttribute 
{ 
    public override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     IPrincipal user = filterContext.HttpContext.User; 

     if(user != null && user.Identity.IsAuthenticated) 
     { 
      MembershipUser membershipUser = Membership.GetUser(); 

      if (PasswordExpired) // Your logic to check if password is expired... 
      { 
       filterContext.HttpContext.Response.Redirect(
        string.Format("~/{0}/{1}?{2}", MVC.SGAccount.Name, MVC.SGAccount.ActionNames.ChangePassword, 
        "reason=expired")); 

      } 
     } 

     base.OnAuthorization(filterContext); 
    } 
} 

注:我用T4MVC检索在上面的代码中的控制器和动作名称。

使用此属性标记除“AccountController”之外的所有控制器。这样做不会有过期密码的用户将能够浏览该网站。

这里有一个职位,我与一些加分的主题所做的:

User Password Expired filter attribute in ASP.NET MVC

0

我使用(4.5)MVC5所用的代码,而仅仅略微修改了它在Asp.NET实现。 NET身份提供商。只是把它留在这里为下一个家伙/加仑:)

void Application_PostAuthenticateRequest(object sender, EventArgs e) 
    { 
     if (this.User.Identity.IsAuthenticated) 
     { 
      WisewomanDBContext db = new WisewomanDBContext(); 

      // get user 
      var userId = User.Identity.GetUserId(); 
      ApplicationUser user = db.Users.Find(userId); 

      // has their password expired? 
      if (user != null && user.PasswordExpires <= DateTime.Now.Date 
       && !Request.Path.EndsWith("/Manage/ChangePassword")) 
      { 
       Response.Redirect("~/Manage/ChangePassword"); 
      } 

      db.Dispose(); 
     } 
    }