2012-09-18 10 views
5

Estoy intentando redirigir al usuario a una acción diferente si su dirección de correo electrónico no se ha validado. La cuestión es que no quiero que se desconecten, solo quiero redirigirlos. Cuando hago esto en OnAuthorization para el controlador, redirige como se esperaba, pero el usuario no está autenticado. No estoy seguro de por qué es esto. Mi código se ve así:La redirección de MVC en OnAuthorization provoca que la autorización falle

protected override void OnAuthorization(AuthorizationContext filterContext) 
    { 
     base.OnAuthorization(filterContext); 

     //_applicationService.CurrentUser is populated correctly at this point 
     // from Controller.User 
     if (_applicationService.CurrentUser != null) 
     { 
      if (_applicationService.CurrentUser.EmailVerified != true) 
      { 
       var url = new UrlHelper(filterContext.RequestContext); 
       var verifyEmailUrl = url.Action("EmailVerificationRequired", "Account", null); 
       filterContext.Result = new RedirectResult(verifyEmailUrl); 
      } 
     } 

    } 

Nota: He eliminado el código innecesario para hacerlo más claro. _applicationService.CurrentUser se completa con el usuario actual, y el usuario se autenticó correctamente cuando llega a ese punto. Pero después de la redirección, el usuario ya no está autenticado.

¿Cómo puedo lograr esta redirección sin afectar la autorización de usuario incorporada?

He intentado poner mi código en OnActionExecuting, y también he intentado implementarlo en un ActionFilterAttribute personalizado, pero donde sea que ponga este redireccionamiento en él impide que el 'Usuario' (es decir: System.Security.Principal .IPrincipal Controller.User) no se autenticará.

¿Qué me falta aquí? Espero que esto tenga sentido. Cualquier ayuda muy apreciada.

En respuesta a la solicitud de Darin para mi acción de acceso:

[HttpPost] 
    [AllowAnonymous] 
    public ActionResult Login(LoginViewModel model, string returnUrl) 
    { 
     string errorMessage = "The username or password is incorrect"; 

     if (ModelState.IsValid) 
     { 
      if (_contextExecutor.ExecuteContextForModel<LoginContextModel, bool>(new LoginContextModel(){      
       LoginViewModel = model 
      })) 
      { 
       ViewBag.CurrentUser = _applicationService.CurrentUser; 
       _formsAuthenticationService.SetAuthCookie(model.LoginEmailAddress, model.RememberMe); 

       if (_applicationService.IsLocalUrl(returnUrl)) 
       { 
        return Redirect(returnUrl); 
       } 

       return RedirectToAction("Index", "Home").Success("Thank you for logging in."); 
      } 
      else 
      { 
       errorMessage = "Email address not found or invalid password."; 
      } 
     } 

     return View(model).Error(errorMessage); 
    } 
+0

¿Podría mostrar cómo está autenticando al usuario, su acción 'LogOn'? –

+0

@DarinDimitrov - He agregado mi acción de inicio de sesión según lo solicitado. – soupy1976

+0

¡Esto es justo lo que he estado buscando! Ahorro mucho tiempo – JosephDoggie

Respuesta

3

Bien, ahora he encontrado dónde me estaba yendo mal. El problema era que yo estaba siendo un poco de un matón y yo no entendía completamente lo que estaba ocurriendo cuando estaba haciendo:

filterContext.Result = new RedirectResult(verifyEmailUrl); 

No me daba cuenta de que en realidad estoy empezando una nueva solicitud con esto, Creí equivocadamente que solo estaba redirigiendo a otra acción. Parece obvio ahora que esta será una nueva solicitud.

Entonces, el problema era que mi acción EmailVerificationRequired no autorizaba al usuario y, por lo tanto, cuando llegó a esta acción, el usuario actual era nulo. Entonces la solución fue agregar la autorización a esa acción y ahora todo está bien.

Gracias por su ayuda chicos.

0

Puede manejar esto en su ActionResult inicio de sesión. Trate de colocar el código

 if (_applicationService.CurrentUser.EmailVerified != true) 
     { 
      FormsAuthentication.SignOut(); 
      return RedirectToAction("EmailVerificationRequired", "Account"); 
     } 

inmediatamente después de esta línea:

_formsAuthenticationService.SetAuthCookie(model.LoginEmailAddress, model.RememberMe);  

siguientes, establecer puntos de interrupción y paso a través de la acción de acceso. Si no llega a la línea if (_applicationService.CurrentUser.EmailVerified! = True), esto indica que su usuario no está autenticado y que tiene un problema diferente al tratar.

+1

Gracias por su ayuda. Lo que pasa es que quiero verificar esto cada vez que se acceda a cualquier acción que requiera autenticación. De lo contrario, un usuario que haya iniciado sesión pero cuya dirección de correo electrónico no haya sido verificada aún podrá acceder a partes del sitio ingresando la URL. Por eso lo quería en OnAuthorization, en lugar de simplemente ponerlo en la acción de inicio de sesión. – soupy1976

+0

@ soupy1976 En función de su comentario, edité el ejemplo del código para evitar que el usuario acceda a partes seguras del sitio sin que se haya autenticado y se haya verificado el correo electrónico. Espero que esto ayude. – Tarzan

+0

gracias de nuevo por su ayuda Tarzán. El problema al colocar este cheque en la acción de inicio de sesión es que el usuario aún podría acceder al contenido escribiendo la URL en el navegador (si lo sabían o si lo habían guardado en su historial o algo así). Necesito hacer este control en la autorización durante la solicitud de página real, en lugar de simplemente verificarlo cuando inician sesión, de lo contrario, apenas hay seguridad. – soupy1976

Cuestiones relacionadas