gpt4 book ai didi

asp.net-mvc - 使用 WIF 和 jquery ajax 请求时 ASP.NET MVC 3 中的 session Cookie 过期处理

转载 作者:行者123 更新时间:2023-12-01 00:03:50 24 4
gpt4 key购买 nike

我的项目正在使用 WIF (但这对于这个问题的上下文来说并不重要。您可以使用处理身份验证的替代框架。问题是关于在执行 ajax 请求时处理身份验证失败的问题) 。不过,就我而言,我编写了继承自 ClaimsAuthenticationManager 的自定义服务器逻辑,并处理身份验证:

public override IClaimsPrincipal Authenticate(string resourceName, IClaimsPrincipal incomingPrincipal)
{
if (incomingPrincipal != null && incomingPrincipal.Identity.IsAuthenticated)
{
// add some custom claims
}
return incomingPrincipal;
}

现在,在我删除所有 session Cookie 后,结束然后再次进入任意页面,我会被重定向到 WIF 提供的登录页面,并被要求再次登录。一切都按预期进行。

但是,如果我发出 ajax 请求,则会出现错误,该错误会被以下内容拦截:

$(document).ready(function () {
$.ajaxSetup({
error: function (XMLHttpRequest, textStatus, errorThrown) {
// do something
}
});
});

不幸的是XMLHttpRequest对象不会返回任何有意义的消息,基于此我可以像其他人一样以任何其他方式处理这种错误。在这种特殊情况下,我只希望应用程序重定向到登录页面 - 就像正常请求一样。

enter image description here

在执行 ajax 调用时,会调用来自 ClaimsAuthenticationManagerAuthenticate 方法。 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, textStatus, xhr) {
}
});

因为我的框架处理身份验证,当 token 过期时,它会将 http 状态 302 放入响应中。因为我不希望浏览器透明地处理 302 响应,所以我在 Global.asax 中捕获它,并将状态更改为 200 OK。此外,我添加了 header ,它指示我以特殊方式处理此类响应:

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, textStatus, 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请求(如果它们没有明显地重新定义beforeSend事件):

$.ajaxSetup({
beforeSend: checkPulse,
error: function (XMLHttpRequest, textStatus, 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, textStatus, xhr) {
if (xhr.getResponseHeader('REQUIRES_AUTH') === '1') {
XMLHttpRequest.abort(); // terminate further ajax execution
window.location = location;
}
}
});
}

Controller 方法可以是任何最简单的方法:

[Authorize]
public virtual void CheckPulse() {}

Application_EndRequest() 与以前一样。

关于asp.net-mvc - 使用 WIF 和 jquery ajax 请求时 ASP.NET MVC 3 中的 session Cookie 过期处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11049690/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com