【问题标题】:MVC Redirection in OnAuthorization causes authorization to failOnAuthorization 中的 MVC 重定向导致授权失败
【发布时间】:2012-09-18 16:23:07
【问题描述】:

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

    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 中实现它,但是无论我把这个重定向放在哪里都会阻止“用户”(即:System.Security.Principal. IPrincipal Controller.User) 获得身份验证。

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

响应达林对我的登录操作的请求:

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

【问题讨论】:

  • 您能否展示您如何验证用户身份 - 您的 LogOn 操作?
  • @DarinDimitrov - 我已按要求添加了登录操作。
  • 这正是我一直在寻找的!节省了很多时间

标签: c# asp.net-mvc asp.net-mvc-3 forms-authentication


【解决方案1】:

好的,我现在找到了哪里出错了。问题是我有点像个傻瓜,我没有完全理解我做的时候发生了什么:

filterContext.Result = new RedirectResult(verifyEmailUrl);

我没有意识到我实际上是在用这个开始一个新的请求,我错误地认为我只是重定向到另一个动作。现在看来,这将是一个新请求。

所以,问题在于我的EmailVerificationRequired 操作未授权用户,因此当它执行此操作时,当前用户为空。所以修复是向该操作添加授权,现在一切正常。

感谢你们的帮助。

【讨论】:

    【解决方案2】:

    您可以在登录操作结果中处理此问题。尝试放置

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

    此行之后的代码:

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

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

    【讨论】:

    • 感谢您的帮助。问题是,每次访问任何需要身份验证的操作时,我都想检查一下。否则,已登录但电子邮件地址未经验证的用户仍然可以通过输入 URL 来访问网站的某些部分。这就是为什么我希望在 OnAuthorization 中使用它,而不是仅仅将其放入登录操作中。
    • @soupy1976 根据您的评论,我编辑了代码示例,以防止用户在未经身份验证和电子邮件验证的情况下访问网站的安全部分。希望这会有所帮助。
    • 再次感谢泰山的帮助。将此检查放入登录操作的问题在于,用户仍然可以通过在浏览器中输入 url 来访问内容(如果他们碰巧知道它或者将其保存在他们的历史记录中或其他东西中)。我需要在实际页面请求期间检查授权,而不是在他们登录时检查授权,否则几乎没有任何安全性。
    • @soupy1976,“FormsAuthentication.SignOut();”行将阻止用户通过在浏览器中输入 url 来访问其他内容。无论如何,听起来你用另一种方法找到了一个很好的解决方案。干杯。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-18
    • 2017-01-16
    • 1970-01-01
    • 2016-04-16
    • 1970-01-01
    • 2020-12-18
    相关资源
    最近更新 更多