asp.net-mvc – 使用WIF和jquery ajax请求时,ASP.NET MVC 3中的
我的项目我正在使用WIF(但这对于这个问题的上下文并不重要.你可以使用替代框架处理你的身份验证.问题是在执行ajax请求时处理身份验证失败).不过,就我而言,我编写了自定义服务器逻辑,它继承自ClaimsAuthenticationManager,并处理身份验证:
public override IClaimsPrincipal Authenticate(string resourceName,IClaimsPrincipal incomingPrincipal) { if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated) { // add some custom claims } return incomingPrincipal; } 现在,在我删除所有会话Cookie后,再次输入任何页面,我被重定向到WIF服务的登录页面,我被要求再次登录.一切都按预期工作. 但是如果我做了一个ajax请求,我就会收到一个错误,这个错误被拦截了: $(document).ready(function () { $.ajaxSetup({ error: function (XMLHttpRequest,textStatus,errorThrown) { // do something } }); }); 不幸的是,XMLHttpRequest对象没有返回任何有意义的消息,基于此我可以像其他人一样以任何其他方式处理这种错误.在这种特殊情况下,我只希望应用程序重定向到登录页面 – 正常请求就是这样. 在执行ajax调用时,将调用来自ClaimsAuthenticationManager的Authenticate方法. Identity.IsAuthenticated返回false,方法结束,所有操作都完成.甚至不调用BaseController的OnAuthorization方法,因此我无法将任何状态传递给ajax结果对象. protected override void OnAuthorization(AuthorizationContext filterContext) { if (filterContext.HttpContext.Request.IsAjaxRequest() && !User.Identity.IsAuthenticated) { //do something,for example pass custom result to filterContext } base.OnAuthorization(filterContext); } 如何解决这个难题? 解决方法
我找到了一些关于此的资源(参见答案的底部),并与以下解决方案混淆:
在执行ajax请求时,我指定我想要json: $.ajax({ url: action,type: 'POST',dataType: 'json',data: jsonString,contentType: 'application/json; charset=utf-8',success: function (result,xhr) { } }); 因为我的框架处理身份验证,所以当令牌过期时,它会将http状态302置于响应中.因为我不希望我的浏览器透明地处理302响应,所以我在Global.asax中捕获它,并将状态更改为200 OK.另外,我添加了标题,指示我以特殊方式处理此类响应: protected void Application_EndRequest() { if (Context.Response.StatusCode == 302 && (new HttpContextWrapper(Context)).Request.IsAjaxRequest()) { Context.Response.StatusCode = 200; Context.Response.AddHeader("REQUIRES_AUTH","1"); } } 响应内容未正确序列化为json,这会导致解析错误.调用错误事件,在其中执行重定向: $(document).ready(function () { $.ajaxSetup({ error: function (XMLHttpRequest,errorThrown) { if (XMLHttpRequest.getResponseHeader('REQUIRES_AUTH') === '1') { // redirect to logon page window.location = XMLHttpRequest.getResponseHeader('location'); } // do sth else } }); }); 有关更多说明,请参见How to manage a redirect request after a jQuery Ajax call和此处How do you deal with AJAX requests when user session expires,or where the request terminates in a 302. 更新: 同时,我想出了新的解决方案,在我看来更好,因为可以应用于开箱即用的所有ajax请求(如果他们没有明确重新定义发送事件): $.ajaxSetup({ beforeSend: checkPulse,error: function (XMLHttpRequest,errorThrown) { document.open(); document.write(XMLHttpRequest.responseText); document.close(); } }); function checkPulse(XMLHttpRequest) { var location = window.location.href; $.ajax({ url: "/Controller/CheckPulse",type: 'GET',async: false,beforeSend: null,success: function (result,xhr) { if (xhr.getResponseHeader('REQUIRES_AUTH') === '1') { XMLHttpRequest.abort(); // terminate further ajax execution window.location = location; } } }); } 控制器方法可以是最简单的: [Authorize] public virtual void CheckPulse() {} Application_EndRequest()与以前保持一致. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- asp.net – IIS 7中的会话超时
- 使用log4net和ASP.NET跟踪会话变量
- asp.net-mvc-2 – 使用Html.LabelFor显示人类可读的标签?
- asp.net-mvc-4 – 登录后WebSecurity.CurrentUserName和Use
- asp.net-mvc – DropDownList不选择SelectList中的选定项
- asp.net-mvc – CSS / Javascript缩小和捆绑在MVC中究竟是如
- asp.net-mvc – 如果用户在int字段中放入非数字字符串,则自
- 使用LINQ生成Where的SQL语句
- asp.net-mvc – 单元测试MVC控制器
- asp.net-mvc – 如何在.NET Web API项目中存储全局每个请求
- 模型 – 视图 – 控制器 – ASP.NET MVC:将View
- asp.net-mvc-3 – 从控制器发送电子邮件
- Asp.net和windows身份验证
- asp.net-mvc-2 – ASP.NET-MVC 2 DataAnnotation
- vs .net CS0006 C# 未能找到元数据文件 .dll
- asp.net-mvc-3 – 用于API访问的WCF或Asp.Net MV
- asp.net-mvc – MVC控制器操作参数为null
- asp.net-core – 当前上下文中不存在名称“SqlSe
- asp.net – FormsAuthentication:是否安全?
- asp.net – Visual C#中事件的下拉列表在哪里?