gpt4 book ai didi

asp.net - AJAX 和 FormsAuthentication,如何防止 FormsAuthentication 覆盖 HTTP 401?

转载 作者:可可西里 更新时间:2023-11-01 15:05:05 26 4
gpt4 key购买 nike

在一个配置了 FormsAuthentication 的应用程序中,当用户在没有授权 cookie 或过时的 cookie 的情况下访问 protected 页面时,ASP.NET 发出 HTTP 401 Unauthorized,然后 FormsAuthentication 模块在请求结束之前拦截此响应,并且将其更改为 HTTP 302 Found,设置 HTTP header “Location:/path/loginurl”以便将用户代理重定向到登录页面,然后浏览器转到该页面并检索不 protected 登录页面,获取 HTTP 200 OK。

在没有考虑 AJAX 的情况下,这确实是一个非常好的主意。

现在我的应用程序中有一个返回 JSON 数据的 url,它需要对用户进行身份验证。一切正常,问题是如果 auth cookie 过期,当我的客户端代码调用服务器时,它将获得带有登录页面 html 的 HTTP 200 OK,而不是 HTTP 401 Unauthorized(因为前面已经解释过)。然后我的客户端试图将登录页面 html 解析为 json,但失败了。

接下来的问题是:如何处理来自客户端的过期身份验证?应对这种情况最优雅的解决方案是什么?我需要知道调用何时成功,我想使用 HTTP 语义来完成。

是否有可能以安全的跨浏览器方式从客户端读取自定义 HTTP header ?如果请求是 AJAX 请求,有没有办法告诉 FormsAuthenticationModule 不执行重定向?有没有一种方法可以像覆盖 HTTP 请求方法一样使用 HTTP header 来覆盖 HTTP 状态?

我需要表单例份验证,我想避免重写该模块或编写我自己的表单例份验证模块。

问候。

最佳答案

我有同样的问题,必须在 MVC 中使用自定义属性。您可以轻松地将其调整为在 Web 表单中工作,如果您的所有页面都继承自某个基页,您可以覆盖基页中的页面授权(MVC 中的全局属性允许相同的事情 - 为所有 Controller /操作覆盖 OnAuthorization 方法申请)

这是属性的样子:

public class AjaxAuthorizationAttribute : FilterAttribute, IAuthorizationFilter
{
public void OnAuthorization(AuthorizationContext filterContext)
{
if (filterContext.HttpContext.Request.IsAjaxRequest()
&& !filterContext.HttpContext.User.Identity.IsAuthenticated
&& (filterContext.ActionDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true).Count() > 0
|| filterContext.ActionDescriptor.ControllerDescriptor.GetCustomAttributes(typeof(AuthorizeAttribute), true).Count() > 0))
{
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();
}
}
}

注意需要调用HttpContext.Response.End();否则您的请求将被重定向到登录(因此我失去了一些头发)。

在客户端,我使用了 jQuery ajaxError 方法:

var lastAjaxCall = { settings: null, jqXHR: null };
var loginUrl = "yourloginurl";

//...
//...

$(document).ready(function(){
$(document).ajaxError(function (event, jqxhr, settings) {
if (jqxhr.status == 401) {
if (loginUrl) {
$("body").prepend("<div class='loginoverlay'><div class='full'></div><div class='iframe'><iframe id='login' src='" + loginUrl + "'></iframe></div></div>");
$("div.loginoverlay").show();
lastAjaxCall.jqXHR = jqxhr;
lastAjaxCall.settings = settings;
}
}
}

}

这在当前页面上显示了 iframe 中的登录(看起来用户被重定向了,但你可以改变它),当登录成功时,这个弹出窗口被关闭,并且重新发送原始 ajax 请求:

if (lastAjaxCall.settings) {
$.ajax(lastAjaxCall.settings);
lastAjaxCall.settings = null;
}

这允许您的用户在 session 过期时登录,而不会丢失他们在上次显示的表单中输入的任何工作或数据。

关于asp.net - AJAX 和 FormsAuthentication,如何防止 FormsAuthentication 覆盖 HTTP 401?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7532261/

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