前言:

当用AJAX请求一个资源时,服务器检查到认证过期,会重新返回302,通过HTTP抓包,是看到请求了登录页面的,但是JS是不会进行跳转到登录页面。

使用环境:

ASP.NET MVC 4

JQUERY EASY UI

待解决的问题

1,如果AJAX请求时认证实效,那么跳转到登录页面重新认证,然后才能进行其它操作。(必须解决)

2,在认证成功之后最好不要返回首页,然后用户又得重新进行进入刚才页面。

解决方法

后端

添加一个自定义的AuthorizeAttribute

实现原理:如果是AJAX请求,并且没有进行授权,那么就返回 HTTP 401,代码如下:

Code public class MyAuth: AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest()
&& !filterContext.HttpContext.User.Identity.IsAuthenticated
&& (filterContext.ActionDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true).Any()
|| filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(
typeof(AuthorizeAttribute),
true).Any()))
{
filterContext.HttpContext.SkipAuthorization = true;
filterContext.HttpContext.Response.Clear();
filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.Unauthorized;
filterContext.Result = new HttpUnauthorizedResult("Unauthorized");
filterContext.Result.ExecuteResult(filterContext.Controller.ControllerContext);
filterContext.HttpContext.Response.End();
}
else base.OnAuthorization(filterContext);
} }

前端

如果想让所有页面都能捕获401错误,那么就需要在模版页_Layout.cshtml中用JS进行判,代码如下:

Code  var lastAjaxCall = { settings: null, jqXHR: null };
var loginUrl = "/Login/Index?AJAX_Login=1"; //...
$(document).ready(function() {
$(document).ajaxError(function(event, jqxhr, settings) {
if (jqxhr.status == 401) {
$("#dialog").prepend("<div id='LoginWindow' class='easyui-dialog' style='width:400px;height:300px;' closed='true' modal='true' title='再次认证'><iframe scrolling='auto' id='openXXXIframe' frameborder='0' src='" + loginUrl + "' style='width:100%;height:100%;'></iframe></div>");
$.parser.parse('#dialog');
$('#LoginWindow').dialog('open');
lastAjaxCall.jqXHR = jqxhr;
lastAjaxCall.settings = settings;
}
});
});

虽然现在实现了认证。

那么如何在登录页面认证成功之后自动把该窗口给关闭了?

因为是用iframe嵌套的登录页面,所以这个属性很重要“parent”

实现方式:

1,在_Layout.cshtml中再加一个JS方法,用于登录成功后的回调函数,代码如下:

Code  function LoginSuccessCallBack() {
$('#LoginWindow').dialog('close');
$('#LoginWindow').empty(); if (lastAjaxCall.settings) {
$.ajax(lastAjaxCall.settings);
lastAjaxCall.settings = null;
}
}

2,在Controller中获取传过来的参数:
            ViewBag.AJAX_Login = Request.QueryString["AJAX_Login"];
在VIEW中

如果认证成功,就调用LoginSuccessCallBack方法关闭窗口,在重新获取刚才没有请求成功的数据。

Code                         var ajaxLogin = '@ViewBag.AJAX_Login';
if (ajaxLogin == 1) {
parent.LoginSuccessCallBack();
} else {
window.location.href = "/Home/index";
}

参考:

http://www.cnblogs.com/dudu/p/3384234.html

http://stackoverflow.com/questions/2472578/is-it-possible-to-use-redirecttoaction-inside-a-custom-authorizeattribute-clas/2472878#2472878

http://stackoverflow.com/questions/2580596/how-do-you-handle-ajax-requests-when-user-is-not-authenticated

http://stackoverflow.com/questions/7532261/ajax-and-formsauthentication-how-prevent-formsauthentication-overrides-http-401/7628655#7628655

解决由AJAX请求时forms认证实效的重新认证问题的更多相关文章

  1. 解决Ajax请求时无法重定向的问题

    今天发现,当使用Ajax请求时,如果后台进行重定向到其他页面时是无法成功的,只能在浏览器地址栏输入才能够实现重定向. Ajax默认就是不支持重定向的,它是局部刷新,不重新加载页面. 需要实现的功能是, ...

  2. 只要发生ajax请求时加载旋转的按钮

    定义一个变量 全局 c 只要发生ajax时给c++ 当ajax请求success或者error时,c--; 对加载的按钮添加个事件   监听 c  如果c得值没变化  则隐藏按钮   如果变化了则显示 ...

  3. AJAX请求时status返回状态明细表(转)

    转自:http://www.cnblogs.com/wangking/p/6530904.html AJAX请求时status返回状态明细表 readyState的五种状态2010-03-04 18: ...

  4. AJAX请求时status返回状态明细表

    AJAX请求时status返回状态明细表 readyState的五种状态2010-03-04 18:24对于readyState的五种状态的描述或者说定义,很多Ajax书(英文原版)中大都语焉不详 在 ...

  5. Laravel 解决在ajax 请求下不能保存session的问题

    Laravel 解决在ajax 请求下不能保存session的问题 \Session::put('isLogin',true); // 你要保存的session key \Session::put(' ...

  6. layui表单提交使用form.on('submit(sub)',function (){}) 使用ajax请求时回调不执行的原因及解决方法

    ayui使用官方的表单模块form.on('submit(sub)',function (){}) 提交,使用ajax请求向后台请求一个执行结果,根据结果进行处理,出现回调无法执行,并且页面出现了刷新 ...

  7. AJAX请求 $.ajaxSetup方法的使用:设置AJAX请求的默认参数选项,当程序中需要发起多个AJAX请求时,则不用再为每一个请求配置请求的参数

    定义和用法ajaxSetup() 方法为将来的 AJAX 请求设置默认值.语法$.ajaxSetup({name:value, name:value, ... }) 该参数为带有一个或多个名称/值对的 ...

  8. AJAX请求时status返回状态明细表 readyState的五种状态

    在<Pragmatic Ajax A Web 2.0 Primer >中偶然看到对readyStae状态的介绍,感觉这个介绍很实在,摘译如下: 0: (Uninitialized) the ...

  9. 在发送ajax请求时加时间戳或者随机数去除js缓存

    在发送ajax请求的时候,为了保证每次的都与服务器交互,就要传递一个参数每次都不一样,这里就用了时间戳 大家在系统开发中都可能会在js中用到ajax或者dwr,因为IE的缓存,使得我们在填入相同的值的 ...

随机推荐

  1. 无插件,无com组件,利用EXCEL、WORD模板做数据导出(一)

    本次随笔主要讲述着工作中是如何解决数据导出的,对于数据导出到excel在日常工作中大家还是比较常用的,那导出到word呢,改如何处理呢,简单的页面导出问题应该不大,但是如果是标准的公文导出呢,要保证其 ...

  2. 查看webdriver针对浏览器的一些函数

    在用webdriver对浏览器进行操作时,很多操作并不是那么好找,后来在朋友的推荐下可以用下面的方法来寻找针对浏览器的一些操作,函数或属性等,这样方便我们可以查找一些方法去完成我们要的操作. 下面是查 ...

  3. iperf——网络性能测试工具

    一.前言 工作中遇到需要测试Linux服务器网卡占用率的场景,查阅资料后,发现iperf是一款合适的网络测速工具. 下面讲解一下如何使用iperf做网络性能测试. 二.基础知识 先补充一些基础知识: ...

  4. dreamwave基础

    WEBcs架构需要在客户段安装程序, 需要安装程序, 工作量会比较大, 需要安装和维护, 比如以后系统升级, 会很麻烦. 优点是一些业务逻辑可以在客户端, 可以减少服务器的一些压力, 客户端的界面操作 ...

  5. ECMAScript5新特性之获取对象特有的属性

    'use strict'; // 父类 function Fruit(){ } Fruit.prototype.name = '水果'; // 子类 function Apple(desc){ thi ...

  6. 网页中引用优酷视频去广告自动播放代码[xyytit]

    很多时候需要在网站中加入视频,可视频太大放自己服务器上太占空间,可以把视频上传到优酷网上,这样节省了空间,打开速度方面也会有不少提升.下面教大家如何引用自动播放的优酷视频.把下面的代码加在你网页适当位 ...

  7. discuz的diy功能介绍

    可以通过页面操作的方式,完成页面布局设计,数据聚合,样式等常见的页面处理功能.   以管理员登陆discuz的前台时,会出现一个diy按钮. 流程,先设计框架,再完成数据的聚合.     定义模板时, ...

  8. 【转】MEF程序设计指南二:Silverlight中使用CompositionInitializer宿主MEF

    MEF可以在传统应用程序中使用(包括桌面的Winform.控制台程序和Web的ASP.NET),也可以在RIA的Silverlight中使用.在Silverlight中只是宿主的方式有所不同,实际上在 ...

  9. C语言跳表(skiplist)实现

    一.简介 跳表(skiplist)是一个非常优秀的数据结构,实现简单,插入.删除.查找的复杂度均为O(logN).LevelDB的核心数据结构是用跳表实现的,redis的sorted set数据结构也 ...

  10. 5 个关键点!优化你的 UI 原型设计

    当你和你的团队着手开始一个产品开发的时候,最开始的一步一般是绘制线框图,这是大部分产品项目的第一步,它不复杂但是却对整个产品的完成形态和质量有着至关重要的作用. 很多刚开始工作设计师或者产品经理都会提 ...