2008-12-08 25 views
21

Estoy usando membresía de ASP.NET para la autenticación de mi aplicación web. Esto funciono muy bien para mi. Ahora tengo que implementar la caducidad de la contraseña.expiración de la contraseña de membresía ASP.NET

Si la contraseña ha caducado, el usuario debe ser redirigido a la pantalla ChangePassword y no se le debe permitir el acceso a ninguna otra parte de la aplicación sin cambiar la contraseña.

Hay muchas páginas aspx. Una solución podría ser redireccionar a la pantalla ChangePasswordOnInit de cada aspx si la contraseña ha expirado. ¿Hay alguna otra solución o recomendación?

Gracias, Jai

Respuesta

13

Se podría añadir un controlador de eventos para el evento HttpApplication.PostAuthenticateRequest en global.asax y manejar la redirección allí.

+6

Eso es lo que haría, combinado con el uso de la propiedad LastPasswordChangedDate del proveedor de suscripciones para determinar cuando caduque. – technophile

6

Acabo de implementar esto en aproximadamente una hora, sin necesidad de modificar su página base. Esto es lo que tiene que hacer:

  1. Responder a la LoggingIn caso del control de miembros

  2. Encuentra el usuario en la base de datos de miembros y obtener LastPasswordChangedDate

  3. Usando un intervalo de tiempo, comparar esto con la fecha actual y decidir si la contraseña se modificó por última vez más que el número requerido de días. Me sale este valor a partir de web.config

  4. Si expiró, redirigir a la pantalla ChangePassword

+1

Esto no atrapará a los usuarios que tienen un ticket de autenticación existente ("recordarme"). La solución de csgero es correcta. – Brett

+0

Sí, si actualmente están autenticados diría que no es un gran problema, a menos que haga que sus cookies sean válidas hasta el infinito. Tal vez si detecta que ya están conectados y caducados, simplemente configure la cookie para que caduque en 20 minutos más o menos, cada vez. Luego, cuando vuelvan, tendrán que cambiarlo. –

+1

El problema con la comprobación en PostAuth también es una tonelada de actividad del sistema adicional para cada solicitud. Siempre que sus tickets venzan con bastante frecuencia, no debería haber mucho problema, O simplemente ejecute el código de PostAuth por más de 1 día después de su tiempo de espera. Esto garantiza que cualquier persona que acceda al sitio con un boleto de autenticación de formularios válido se verifique. Entonces, si no inician sesión durante ese tiempo, los formularios auth tickets caducarán y LogginIn incluso podrá utilizarse. Después de +1 día después del vencimiento del ticket, puede eliminar el evento PostAuth. También querrá verificar al iniciar sesión –

26

Además de csgero's answer, he encontrado que no es necesario añadir explícitamente un controlador de eventos para este evento en ASP.Net 2.0 (3.5).

puede simplemente crear el método siguiente en global.asax y se cablea de que:

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"); 
     } 
    } 
} 
+1

Gran respuesta y código de ejemplo. ¡Gracias! – joshschreuder

+0

Tenga en cuenta la solución de Ben Rethmeier a continuación (http://stackoverflow.com/a/9879682/324817) para que sea posible cambiar la contraseña en la pantalla de cambio de contraseña. – joshschreuder

+0

Gracias @shrodes: actualicé mi respuesta para incluir la solución de Ben Rethmeier: o) – Andrew

9

Además de Andrew's answer, encontré que necesita para comprobar que el usuario no está ya en la página de cambio de contraseña, o que nunca será capaz de cambiar su contraseña en realidad, y por lo tanto nunca deje el lugar de cambio de contraseña:

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"); 
      } 
     } 
    } 
+0

+1: buen punto Ben: o) – Andrew

4

llegué aquí buscando una solución a esto, pero mi tecnología actual es ASP.NET MVC. Así que para ayudar a los demás: se puede ampliar el AuthorizeAttribute, y anular OnAuthorization método, como esto:

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

Nota: Yo uso T4MVC para recuperar el controlador y los nombres de acción en el código de seguridad.

Marque todos los controladores con este atributo excepto "AccountController". Al hacerlo, ningún usuario con una contraseña caducada podrá navegar por el sitio.

Aquí hay un post que hice sobre el tema con algunos puntos de bonificación:

User Password Expired filter attribute in ASP.NET MVC

0

que utiliza el código de arriba y sólo ligeramente modificado para aplicar en Asp.NET (4.5) utilizando el MVC5. Proveedor de identidad NET. Acaba de salir de aquí para la próxima individuo/galón :)

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(); 
     } 
    } 
Cuestiones relacionadas