这个问题困扰了我好几天,所以当我发现这个答案可以肯定地解决tvanfosson的答案时,我认为强调答案的核心部分并解决一些相关的问题是值得的。
核心答案非常简单明了:
filterContext.Result = new HttpUnauthorizedResult();
在我的情况下,我继承自一个基础控制器,所以在每个继承它的控制器中,我都要重写OnAuthorize:
protected override void OnAuthorization(AuthorizationContext filterContext)
{
base.OnAuthorization(filterContext)
YourAuth(filterContext)
}
问题出在'YourAuth'中,我尝试了两种方法,认为这不仅可以奏效,还能立即终止请求。然而,事实并非如此。因此,首先介绍两种行不通的方法:
filterContext.RequestContext.HttpContext.Response.Redirect("/Login")
FormsAuthentication.RedirectToLoginPage()
不仅这些方法无效,而且它们也不能结束请求。这意味着以下内容:
if (!success) {
filterContext.Result = new HttpUnauthorizedResult();
}
DoMoreStuffNowThatYouThinkYourAuthorized();
即使上面的答案是正确的,逻辑流仍将继续!因此请记住,在OnAuthorize中仍会触发DoMoreStuff...。因此,要把它放在else中。
但是,使用正确的答案后,尽管OnAuthorize的逻辑流仍将一直持续到结束,但在那之后,你确实会得到你期望的结果:重定向到登录页面(如果你在webconfig的Forms auth中设置了一个登录页面)。
但出乎意料的是,
1)Response.Redirect("/Login")不起作用:Action方法仍然被调用,而
2)FormsAuthentication.RedirectToLoginPage();也是同样的情况:Action方法仍然被调用!
这对我来说似乎完全错误,特别是后者:谁会想到FormsAuthentication.RedirectToLoginPage不会结束请求或执行filterContext.Result = new HttpUnauthorizedResult()的等效操作?