fyn*_*bob 21 authentication asp.net-mvc jquery partial-views authorize-attribute
我有一个视图,使用jQuery从控制器操作加载部分视图.控制器操作使用Authorize属性进行修饰,如果用户在调用该操作被重定向到正确的LogOn页面时超时,则LogOn页面将插入到部分视图已经消失的视图中.
还有另一篇文章在这里描述使用jQuery但遗憾的是它不包含任何代码示例这正是我需要的,因为我不是很熟悉的jQuery(和新的Web开发)的解决方案,我需要得到这个问题的解决我会尽快.
我想要做的就是将用户重定向到正确的LogOn页面,这对我来说非常直接,但到目前为止它似乎并非如此.如果jQuery是要走的路,有人可以发一个代码示例,这真的会帮助我.
谢谢.
Sim*_*olt 33
Pro ASP.NET MVC 2 Framework为此提供了一种解决方案
如果Ajax请求被拒绝授权,那么通常您不希望将HTTP重定向返回到登录页面,因为您的客户端代码不期望这样做并且可能会执行不需要的操作,例如将整个登录页面注入中间用户所在的任何页面.相反,您需要将更有用的信号发送回客户端代码(可能是JSON格式),以解释请求未经授权.您可以按如下方式实现:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后{'Error': 'NotAuthorized', 'LogonUrl': '...'},您将从控制器返回一个JSON对象,然后您可以使用该对象重定向用户.
如果您期望HTML,替代响应可能是返回一个纯字符串,NotAuthorized:<your_url>并检查响应是否与此模式匹配.
401 Unautorized状态代码
由于必须在每个ajax请求的success回调中检查这一点,因此这非常繁琐.能够在全球范围内捕捉这个案例会很高兴.最好的解决方案是401 Unauthorized从服务器返回状态代码并使用jQuery .ajaxError来捕获它,但这在IIS/ASP.NET上是有问题的,因为如果响应具有此状态代码,它致命地将您重定向到登录页面.只要该重定向中<authentication>存在标记web.config就会发生[1]如果您不对其执行某些操作,.
让我们来做点什么吧.这个 hacky方式似乎很好.在你的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;
}
}
Run Code Online (Sandbox Code Playgroud)
(如果有人知道有什么更好的方法可以返回401状态代码,我很乐意听到它.)
通过这样做,当请求是ajax请求时,您将阻止重定向到登录页面的默认行为.因此,您可以AuthorizeAttribute按原样使用默认值,因为它Application_EndRequest 可以处理其余部分.
现在,在jQuery代码中,我们将使用该.ajaxError函数来捕获错误.这是一个全局的ajax事件处理程序,这意味着它将拦截任何ajax调用所产生的每个错误.它可以附加到任何元素 - 在我的例子中,我刚刚选择body因为它始终存在
$("body").ajaxError(function(event, XMLHttpRequest, ajaxOptions, thrownError) {
if (XMLHttpRequest.status == 401) {
alert("unauthorized");
}
});
Run Code Online (Sandbox Code Playgroud)
这样你就可以将重定向逻辑集中在一个地方,而不必在每个该死的ajax请求成功回调上检查它
这个答案提供了另一种解决方案 它使用相同类型的全局事件处理程序,但跳过hacky位.如果您未经过身份验证并且请求是ajax请求,则会向页面添加自定义标头,并在每个请求上检查此标头.ajaxComplete.请注意,链接答案中提供的方法是不安全的,因为它将返回具有可能敏感内容的原始视图,并依赖于javascript将用户重定向到远离它.通过一些修改,它非常棒,因为它不需要任何黑客攻击,逻辑可以集中到一个回调函数.我能看到的唯一缺点就是它没有用语义正确的状态代码回复,因为它实际上不是200 OK因为你是401 Unauthorized
我们可以把它烘焙成另一种习俗 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);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,每次ajax请求完成时,都会检查此标头:
$('body').ajaxComplete(function(event,request,settings){
if (request.getResponseHeader('REQUIRES_AUTH') === '1'){
alert("unauthorized");
};
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5033 次 |
| 最近记录: |