【问题标题】:.NET C#: How to handle forms authentication expiration during an AJAX call.NET C#:如何在 AJAX 调用期间处理表单身份验证过期
【发布时间】:2011-01-21 22:32:37
【问题描述】:

对于上下文,我在 web.config 中设置了表单身份验证超时值,并且正在使用 ASP.NET MVC 1。我认为将我的问题描述为 2 个用例可能是最简单的——第一个会发生什么没有身份验证超时,第二个是身份验证超时:

正常情况:

用户登录应用程序,身份验证计时器开始计时。虽然身份验证期限仍然有效,但用户单击页面上的某些内容会触发 AJAX 调用(通过 jQuery)。我们访问服务器,处理请求,并将部分视图返回给用户(作为ActionResult)。 html 作为 ajax 成功方法的字符串,我将这个 html 注入到页面上的 div 中。这一切都在意料之中。

超时情况:

用户登录应用程序,身份验证计时器开始计时。在 x 时间之后,身份验证期到期。随着到期时间的推移,用户单击页面上的某些内容会触发 AJAX 调用(使用 jQuery)。我们访问了服务器,但身份验证票已过期。 .NET 自动重定向到在设置超时期限的同一 web.config 元素中定义的 loginURL 值。对我来说,这个页面是要求用户输入用户名/密码以登录的登录页面。因此Home/Login控制器操作运行,并最终将完整(非部分)视图作为html字符串返回给ajax的成功方法。这会导致页面爆炸,因为我正在尝试获取整个页面的 html(带有<html> 标签和所有标签)并将其注入页面上的 div 中。

所以这就是我的问题。当身份验证期到期时,.NET 将我重定向到登录页面,我最终将整个页面的 html 返回到 ajax 成功方法。当然,当服务器命中不是 AJAX 调用时,一切正常——它很好地重定向到登录页面。但是我该如何处理这种情况呢?有人有什么想法吗?

谢谢。

【问题讨论】:

    标签: asp.net-mvc ajax timeout forms-authentication


    【解决方案1】:

    所以在票证到期时执行帐户/登录操作

    public Action Login()
    {
       if(Request.IsAjaxRequest())
       return Content(@"<meta http-equiv="refresh" content="1" />");
       //if it is ajax request the div will be filled with this meta tag which will refresh the page
    
    
      return View();
    }
    

    【讨论】:

    • 感谢您的回复。不幸的是,当 .NET 重定向到登录页面时,Request.IsAjaxRequest() 返回 false。当 .NET 意识到身份验证超时并决定访问loginURL 时,可能会生成一个新请求。
    • @Mega Matt 这可能是因为您使用的是 mvc1。 jQuery 进行的所有 AJAX 调用都将添加一个标头以表明它是 AJAX。要检查的标头是 X-Requested-With,当它是 AJAX 调用时,值将是 XMLHttpRequest。尝试调试并查找 Request.Headers["X-Requested-With"]
    • 我在 Request.Headers 中没有“X-Requested-With”。我有“Connection”、“Keep-Alive”、“Accept”、“Accept-Charset”、“Accept-Encoding”、“Accept-Language”、“Cookie”、“Host”、“Referrer”和“User-代理人”。老实说,如果 Request.IsAjaxRequest() 返回 false,我没想到会看到与 AJAX 请求相关的标头。我想这可能仍然与我使用 MVC 1 有关?
    • @Mega Matt atm 我在考虑 mvc 1 或 jQuery 版本
    • Omu,绝对是 MVC 1 的“功能”。我让一位同事在使用 MVC 2 时尝试了同样的事情,并且从 IsAjaxRequest 返回了true。我得升级了。谢谢。
    【解决方案2】:
     public class BasicAuthenticationAttribute : ActionFilterAttribute, IAuthenticationFilter
    {
        public void OnAuthentication(AuthenticationContext filterContext)
        {
            var user = filterContext.HttpContext.User;
            if (user == null || !user.Identity.IsAuthenticated)
            {
                if (filterContext.HttpContext.Request.IsAjaxRequest())
                {
                    filterContext.Result = new JsonResult
                    {
                        JsonRequestBehavior = JsonRequestBehavior.AllowGet,
                        Data = new { redirectTo = FormsAuthentication.LoginUrl }
                    };
                }
                else
                {
                    filterContext.Result = new HttpUnauthorizedResult();
                }
            }
        }
        public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext)
        {
            //  throw new NotImplementedException();
        }
    }
    

    然后你可以按照以下方式使用

    $.get('/foo', function(result) {
    if (result.redirectTo) {
        window.location.href = result.redirectTo;
    } else {
        // standard stuff
    }
    

    });

    【讨论】:

      猜你喜欢
      • 2011-09-24
      • 1970-01-01
      • 2011-11-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-16
      • 2011-03-21
      • 1970-01-01
      相关资源
      最近更新 更多