解决由AJAX请求时forms认证实效的重新认证问题
前言:
当用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
解决由AJAX请求时forms认证实效的重新认证问题的更多相关文章
- 解决Ajax请求时无法重定向的问题
今天发现,当使用Ajax请求时,如果后台进行重定向到其他页面时是无法成功的,只能在浏览器地址栏输入才能够实现重定向. Ajax默认就是不支持重定向的,它是局部刷新,不重新加载页面. 需要实现的功能是, ...
- 只要发生ajax请求时加载旋转的按钮
定义一个变量 全局 c 只要发生ajax时给c++ 当ajax请求success或者error时,c--; 对加载的按钮添加个事件 监听 c 如果c得值没变化 则隐藏按钮 如果变化了则显示 ...
- AJAX请求时status返回状态明细表(转)
转自:http://www.cnblogs.com/wangking/p/6530904.html AJAX请求时status返回状态明细表 readyState的五种状态2010-03-04 18: ...
- AJAX请求时status返回状态明细表
AJAX请求时status返回状态明细表 readyState的五种状态2010-03-04 18:24对于readyState的五种状态的描述或者说定义,很多Ajax书(英文原版)中大都语焉不详 在 ...
- Laravel 解决在ajax 请求下不能保存session的问题
Laravel 解决在ajax 请求下不能保存session的问题 \Session::put('isLogin',true); // 你要保存的session key \Session::put(' ...
- layui表单提交使用form.on('submit(sub)',function (){}) 使用ajax请求时回调不执行的原因及解决方法
ayui使用官方的表单模块form.on('submit(sub)',function (){}) 提交,使用ajax请求向后台请求一个执行结果,根据结果进行处理,出现回调无法执行,并且页面出现了刷新 ...
- AJAX请求 $.ajaxSetup方法的使用:设置AJAX请求的默认参数选项,当程序中需要发起多个AJAX请求时,则不用再为每一个请求配置请求的参数
定义和用法ajaxSetup() 方法为将来的 AJAX 请求设置默认值.语法$.ajaxSetup({name:value, name:value, ... }) 该参数为带有一个或多个名称/值对的 ...
- AJAX请求时status返回状态明细表 readyState的五种状态
在<Pragmatic Ajax A Web 2.0 Primer >中偶然看到对readyStae状态的介绍,感觉这个介绍很实在,摘译如下: 0: (Uninitialized) the ...
- 在发送ajax请求时加时间戳或者随机数去除js缓存
在发送ajax请求的时候,为了保证每次的都与服务器交互,就要传递一个参数每次都不一样,这里就用了时间戳 大家在系统开发中都可能会在js中用到ajax或者dwr,因为IE的缓存,使得我们在填入相同的值的 ...
随机推荐
- windows下多个文件合并成一个文件
如果你拿到的是一堆文件,那么你想把它合并成一个文件来使用,那么按下面的步骤,轻轻松松就可以搞定. 第一步:把所有要合并的文件放到同一个文件下面 第二步:在CMD里面进入到你的文件目录 第三步:输入如下 ...
- Java GC的原理
Java GC(garbage collec,垃圾收集,回收) GC是对JVM中的内存进行标记和回收,Sun公司的JDK用的虚拟机都是HotSpot 对象化的实例是放在heap堆内存中的,这里讲的分代 ...
- WebDriverException: Message: f.QueryInterface is not a function
WebDriverException: Message: f.QueryInterface is not a function 使用webdriver打开c.highpin.cn,结果报错,见下图: ...
- Spring简单获得实体类的实例, 使用ApplicationContext()方法的几点注意事项
今天接触了Spring的初步用法, 感觉跟实例化实体类没啥区别, 像这种简单的代码还不如直接实例化来的方便, 这样使用Spring的话总共需要三个文件 第一个当然是一个实体类了, 定义好属性, get ...
- TZOJ 4746 Xiangqi(模拟棋盘数组)
描述 Xiangqi is one of the most popular two-player board games in China. The game represents a battle ...
- 一个性能较好的JVM参数配置
一个性能较好的web服务器jvm参数配置: -server//服务器模式-Xmx2g //JVM最大允许分配的堆内存,按需分配-Xms2g //JVM初始分配的堆内存,一般和Xmx配置成一样以避免每次 ...
- runloop - 介绍
1. 简介 没有的话 有的话
- iOS 7.0.2 的bug记录
在iOS 7.0.2 版本上,如果从主屏幕进入webapp且webapp进入全屏模式,那么alert和修改window.location到某产品对应的itunes下载页面则无效. 可参考下面的代码示例 ...
- catkin_make 与cmake
http://blog.csdn.net/zyh821351004/article/details/50388429 1. catkin_make 与cmake的关系 程序在cmake编译的流程: ...
- laravel中的old()函数
1.控制器 2.模板