在我们的MVC网站上,我们使用该Authorize属性保护我们的端点,但是当我发生这种情况时,我想将用户重定向到登录屏幕.我的第一个解决方案是对重定向Application_EndRequest在Global.asax.cs:
protected void Application_EndRequest(object sender, EventArgs e)
{
if (Response.StatusCode == (int) HttpStatusCode.Unauthorized)
{
Response.ClearContent();
Response.Redirect("/Account/Login");
}
}
Run Code Online (Sandbox Code Playgroud)
这个问题是我们的一些视图是由AJAX加载的,在这种情况下我们不希望在动态加载的div中显示登录屏幕(这例如在注销后按下后退按钮时会发生).如果请求仍返回登录屏幕,但使用401 Unauthorized状态代码以便我们可以检测到此事件,那会更好.显然这不适用于这种方法,因为重定向依赖于302状态代码.
相反,我宁愿Application_EndRequest用401状态代码"插入"登录屏幕内容.所以,而不是Response.Redirect,我试过这个:
...
Response.ClearContent();
Server.TransferRequest("~/Account/Login");
Response.StatusCode = (int) HttpStatusCode.Unauthorized;
...
Run Code Online (Sandbox Code Playgroud)
重定向工作得很好,但因为这会执行一个新请求,我无法以这种方式设置状态代码,我得到200.仍然没有检测到未经授权的请求.
我也尝试过:
...
Response.ClearContent();
Server.Transfer("~/Account/Login");
Response.StatusCode = (int) HttpStatusCode.Unauthorized;
...
Run Code Online (Sandbox Code Playgroud)
但我得到一个异常"执行/帐户/登录的子请求时出错".
我也尝试过:
...
Response.ClearContent();
HttpContext.Current.RewritePath("~/Account/Login");
Response.StatusCode = (int) HttpStatusCode.Unauthorized;
Response.End();
...
Run Code Online (Sandbox Code Playgroud)
但这引发了异常"线程被中止".我不确定Response.End()是否必要,但没有它,我只是得到一个标准的IIS 401错误.
如何返回登录屏幕的内容,但是有401状态代码?
发送401和ViewObject或RedirectObject并不是MVC框架的工作方式: - 一些帖子巧妙地显示了返回带有View授权过滤器的401.
我指定了MVC框架,但这甚至不是使用HTTP协议的首选方式 .
View()方法返回时,将创建一个ViewResult无论重定向还是视图最终都到达客户端浏览器,
HTTP Return Code中200 - 成功将返回要么
HTTP Return Code中302 - 重定向将被退回这种约定的原因是,服务器正在"处理"重定向.如果用户未获得授权,则服务器会将用户重定向到登录页面.
同样地,在AJAX或异步HTTP请求中,只要返回HTML视图,HTTP请求就被认为是成功的.异步请求不返回重定向(302).
向客户端发送错误代码:
如果您想将401 未经授权的人返回给客户端,这通常意味着您希望客户端通过导航到"登录"或"错误视图"来"处理"未经授权的请求.
$.ajax({
url: loginURL,
data: $("#form").serialize(),
type: "POST",
dataType: "html"
})
.success(function (result, status) {
/*additional logic*/
})
.error(function (xhr, status) {
if (xhr.status == 401)
{
window.location = unauthorizedUrl; //redirect to unauthorized url
}
});
Run Code Online (Sandbox Code Playgroud)
如果要重定向到登录页面并显示错误该怎么办?
如果要重定向到登录页面并显示错误,那么您的问题最有意义
然后,惯例是将您的错误消息添加到ViewbagModelState错误
如:
var user = await signInManager.UserManager.FindByNameAsync(model.UserName);
ModelState.AddModelError("", "Invalid username or password.");
return View(model);
Run Code Online (Sandbox Code Playgroud)
在您的视图中,要有代码来查找错误:
A ValidationSummary会拾取模型错误
@Html.ValidationSummary(true)
Run Code Online (Sandbox Code Playgroud)
这个错误登录尝试的具体示例并不完全符合您的示例.
我找不到重定向用户的图像,因为它们未经授权,但在这种情况下,逻辑类似.错误消息可以使用QueryString,Viewbag等填充.
我尝试了很多不同的方法,所有这些方法都有自己的偷偷摸摸的问题。不确定您的解决方案是如何设置的,但如果您需要执行传输,您可以使用以下方法:
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.RequestContext.HttpContext.Server.TransferRequest("/Account/Login/?NOT_AUTHORISED=TRUE", false);
}
}
Run Code Online (Sandbox Code Playgroud)
您需要将消息传递给下一个请求,使用 QueryString 似乎可以解决问题。尽管您需要记住,任何人都可以设置 QS 参数。
protected void Application_EndRequest(object sender, EventArgs e)
{
if (Request["NOT_AUTHORISED"] == "TRUE")
{
Response.StatusCode = (int) HttpStatusCode.Unauthorized;
}
}
Run Code Online (Sandbox Code Playgroud)
没有重定向,HTTP 状态代码设置为 401。
理想情况下,您希望使用自定义AuthorizeAtrribute然后挂钩到该HandleUnauthorizedRequest方法,然后通过将控制器和视图设置为在AuthorizationContext中调用,将视图返回到登录页面.
public class MyAuthorizeAttribute : AuthorizeAttribute
{
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
if (!filterContext.HttpContext.User.Identity.IsAuthenticated)
{
filterContext.RouteData.Values["controller"] = "home";
filterContext.RouteData.Values["action"] = "login";
filterContext.Result = new ViewResult ();
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = true;
filterContext.HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
}
}
}
Run Code Online (Sandbox Code Playgroud)
注意:这样做的诀窍是确保将以下值设置为true,以避免在设置401状态后表单身份验证接管响应.
HttpContext.Response.SuppressFormsAuthenticationRedirect = true;
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1620 次 |
| 最近记录: |