还有另一篇文章here描述了一个使用jQuery的解决方案,但不幸的是它不包含任何代码示例,这是我需要的,因为我不太熟悉jQuery(和新的Web开发),我需要解决这个问题我会尽快。
所有我想要做的是将用户重定向到正确的logon页面,这对我来说听起来很直接,但到目前为止似乎不是这样。如果jQuery是要走的路,有人可以发布一个代码示例,这真的会帮助我。
谢谢。
解决方法
Pro ASP.NET MVC 2 Framework为此提供了一个解决方案
If an Ajax request is
denied authorization,then usually
you don’t want to return an HTTP
redirection to the login page,because
your client-side code is not
expecting that and may do something
unwanted such as injecting the entire
login page into the middle of
whatever page the user is on. Instead,
you’ll want to send back a more useful
signal to the client-side code,
perhaps in JSON format,to explain
that the request was not authorized.
You could implement this as follows:
public class EnhancedAuthorizeAttribute : AuthorizeAttribute { protected override void HandleUnauthorizedRequest(AuthorizationContext context) { if (context.HttpContext.Request.IsAjaxRequest()) { UrlHelper urlHelper = new UrlHelper(context.RequestContext); context.Result = new JsonResult { Data = new { Error = "NotAuthorized",logonUrl = urlHelper.Action("logon","Account") },JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } else base.HandleUnauthorizedRequest(context); } }
然后,您可以从控制器返回一个JSON对象{‘Error’:’NotAuthorized’,’logonUrl’:’…’},然后您可以使用它来重定向用户。
如果您期待HTML,则可以返回一个简单的字符串,例如NotAuthorized:< your_url>并检查响应是否匹配此模式。
解决方案2,返回和处理401未知状态码
由于这必须检查每个ajax请求的成功回调,这是相当乏味的。能够在全球范围内抓住这个案件将是件好事。最好的解决方案是从服务器返回401未经授权的状态代码,并使用jQuery的.ajaxError
来捕获它,但是这在IIS / ASP.NET上是有问题的,因为如果响应有这样的话,它将致命的重定向到登录页面的StatusCode。只要< authentication>标签存在于web.config中,如果您不做任何事情,此重定向将发生在[1]。
所以我们来做一些事情。 This哈奇的方式似乎很好。在你的global.asax.cs
protected void Application_EndRequest() { if (Context.Response.StatusCode == 302 && Context.Request.RequestContext.HttpContext.Request.IsAjaxRequest()) { Context.Response.Clear(); Context.Response.StatusCode = 401; } }
(如果有人知道有更好的方法返回401状态代码,我很乐意听到。)
通过这样做,当您的请求是ajax请求时,您将阻止重定向到登录页面的默认行为。因此,您可以使用默认的AuthorizeAttribute,因为Application_EndRequest负责其余的。
现在,在jQuery代码中,我们将使用.ajaxError函数来捕获错误。这是一个全局的ajax事件处理程序,这意味着它将拦截任何ajax调用所产生的每个错误。它可以附加到任何元素 – 在我的例子中,我刚刚选择了身体,因为它始终存在
$("body").ajaxError(function(event,XMLHttpRequest,ajaxOptions,thrownError) { if (XMLHttpRequest.status == 401) { alert("unauthorized"); } });
这样你就可以将重定向逻辑集中在一个地方,而不必检查每一个死亡的ajax请求成功回调
This answer提供了一个替代解决方案。它使用相同类型的全局事件处理程序,但跳过黑客位。如果您未通过身份验证,并且请求是ajax请求,并在每个.ajaxComplete
上检查此标题,则会向页面添加自定义页眉。请注意,链接答案中提供的方法不安全,因为它将返回原始视图有可能敏感的内容,并依靠javascript来重定向用户远离它。有了一些修改,它是非常好的,因为它不需要任何黑客,逻辑可以集中到一个回调函数。唯一的缺点就是我看不到它使用语义正确的状态代码来回复,因为它实际上不是200 OK,因为你是401未经授权
我们可以将它烘焙成另一个自定义的EnhancedAuthorizationAttribute
public class EnhancedAuthorizeAttribute : AuthorizeAttribute { protected override void HandleUnauthorizedRequest(AuthorizationContext context) { if (context.HttpContext.Request.IsAjaxRequest()) { context.HttpContext.Response.AddHeader("REQUIRES_AUTH","1"); context.Result = new EmptyResult(); } else { base.HandleUnauthorizedRequest(context); } } } }
现在,每次ajax请求完成时,都会检查这个头文件:
$('body').ajaxComplete(function(event,request,settings){ if (request.getResponseHeader('REQUIRES_AUTH') === '1'){ alert("unauthorized"); }; });