2012-09-18 75 views
5

我试图将用户重定向到其他操作,如果他们的电子邮件地址尚未验证。问题是,我不希望他们被注销,我只是想重定向他们。当我在控制器的OnAuthorization中执行此操作时,它按照预期重定向,但用户未通过身份验证。我不确定这是为什么。我的代码如下所示:OnAuthorization中的MVC重定向导致授权失败

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

    } 

注意:我删除了不必要的代码以使其更清晰。 _applicationService.CurrentUser被当前用户填充 - 并且用户在到达该点时已被正确验证。但是在重定向之后,用户不再被认证。

如何在不影响内置用户授权的情况下实现此重定向?我试过把我的代码放到OnActionExecuting中,我也尝试过在自定义的ActionFilterAttribute中实现它,但是无论我把这个重定向放在哪里,都会阻止'User'(例如:System.Security.Principal .IPrincipal Controller.User)获得身份验证。

我在这里错过了什么?希望这是有道理的。任何帮助非常感谢。

在回答Darin的请求我的登录操作:

[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

你能告诉你如何验证用户 - 你的LogOn行动? –

+0

@DarinDimitrov - 我已按要求添加了我的登录操作。 – soupy1976

+0

这正是我一直在寻找的!节省了很多时间 – JosephDoggie

回答

3

好吧,我现在已经发现我错了。问题是,我是一个有点糊涂人的,我并没有完全明白发生了什么事,当我在做:

filterContext.Result = new RedirectResult(verifyEmailUrl); 

我不知道,我其实开始一个新的请求,这一点,我错误地认为我只是重定向到另一个行动。现在看来这显然是一个新的要求。

所以,问题是我的EmailVerificationRequired行动没有授权用户,因此当它到达这个行动当前用户为空。所以解决方法是将授权添加到该操作中,现在一切正常。

感谢您的帮助球员。

0

你可以在你登录的ActionResult处理这个问题。试试这条线后立即放置

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

代码:

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

接下来,设置断点,并通过登录操作步骤。如果您未达到if(_applicationService.CurrentUser.EmailVerified!= true)行,则表示您的用户未通过身份验证,并且您有不同的问题需要解决。

+1

感谢您的帮助。事情是,我希望每次访问需要身份验证的任何操作时都检查一次。否则,已登录但未通过电子邮件地址验证的用户仍然可以通过输入URL来访问站点的某些部分。这就是为什么我需要在OnAuthorization中使用它,而不是将其放入登录操作中。 – soupy1976

+0

@ soupy1976根据您的评论,我编辑了代码示例,以防止用户访问网站的安全部分,而无需通过身份验证和验证电子邮件。希望这可以帮助。 – Tarzan

+0

再次感谢您的帮助泰山。将此检查放在登录操作中的问题在于,用户仍然可以通过在浏览器中输入网址来访问内容(如果他们碰巧知道或者将其保存在历史记录中)。我需要在实际的页面请求期间检查授权,而不是在他们登录时检查它,否则几乎没有任何安全性。 – soupy1976