我有应用程序与许多ajax操作(使用
JQuery.ajax实现),返回JSON ot html.其中一些只能由授权用户访问,并且我们使用[Authorize]属性进行装饰.对于不是ajax操作,如果用户未授权 – 系统将其重定向到登录页面(在web.config中配置).
但是,这不适用于ajax操作,因为如果用户被授权 – 他加载页面,该cookie到期后,他没有被授权,而不是html块,应该替换旧的,他将我的登录页面放在块内.
我知道我可以手动解决这个问题,例如删除[Authorize]属性,如果用户没有授权,返回特殊的json / empty html.但是我不喜欢这个解决方案,因为我需要重写所有的action和ajax函数.我想要全局解决方案,这样我就不能重写我的动作(可能是自定义授权属性,还是一些http未经授权的结果自定义处理).
解决方法
在global.asax.cs中的代码中添加一个Application_EndRequest处理程序,它将任何302错误(重定向到登录页面)修改为AJAX请求的401(未经授权)错误.这将允许您简单地将控制器的操作按原样处理,并处理重定向(您真的只能通过客户端再次使用用户登录,如果它们不存在).
protected void Application_EndRequest() { // Any AJAX request that ends in a redirect should get mapped to an unauthorized request // since it should only happen when the request is not authorized and gets automatically // redirected to the login page. var context = new HttpContextWrapper( Context ); if (context.Response.StatusCode == 302 && context.Request.IsAjaxRequest()) { context.Response.Clear(); Context.Response.StatusCode = 401; } }
然后在_Layout.cshtml文件中添加一个全局AJAX错误处理程序,当它获得401响应时重定向到您的登录操作.
<script type="text/javascript"> $(function () { $(document).ajaxError(function (e,xhr,settings) { if (xhr.status == 401) { location = '@Url.Action( "login","account" )'; } }); }); </script>
您可能还想尝试Phil Haack博客Prevent Forms Authentication Login Page Redirect When You Don’t Want It中列出的一些技巧