.NET C#: How to handle forms authentication expira

2019-05-17 17:33发布

For context, I have a forms authentication timeout value set in my web.config, and am using ASP.NET MVC 1. I think it might be easiest to state my problem as 2 use cases -- the first one what happens without an authentication timeout, and the second one what happens with an authentication timeout:

Normal case:

The user logs into the app, and the authentication timer starts ticking. While the authentication period is still valid, the user clicks something on the page that triggers an AJAX call (through jQuery). We hit the server, process the request, and return a partial view to the user (as an ActionResult). The html comes through as a string to the ajax's success method, and I take this html and inject it into a div on the page. This is all expected.

Timed out case:

The user logs into the app, and the authentication timer starts ticking. After x amount of time, the authentication period expires. With the expiration time up, the user clicks something on the page that triggers an AJAX call (using jQuery). We hit the server, but the authentication ticket is expired. .NET automatically redirects to the loginURL value defined in the same web.config element that sets the timeout period. For me, this page is the login page where the user is asked to input username/password to log in. So the Home/Login Controller action runs, and eventually returns a full (not partial) view back as a string of html to the ajax's success method. This causes the page to bomb because I'm trying to take a full page's html (with <html> tags and all) and inject it into a div on the page.

So therein lies my problem. When the authentication period has expired, and .NET redirects me to the login page, I end up returning a full page's html to an ajax success method. Of course, everything works fine when the server hit isn't an AJAX call -- it redirects fine to the login page. But how can I handle this case? Does anyone have any ideas?

Thanks.

2条回答
Animai°情兽
2楼-- · 2019-05-17 18:07
 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();
    }
}

and then you can use in following way

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

});

查看更多
仙女界的扛把子
3楼-- · 2019-05-17 18:12

so the Account/Login action get's executed when the ticket expires

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();
}
查看更多
登录 后发表回答