ASP.NET MVC Session Expiration

前端 未结 6 2056
孤街浪徒
孤街浪徒 2021-01-01 21:51

We have an internal ASP.NET MVC application that requires a logon. Log on works great and does what\'s expected. We have a session expiration of 15 minutes. After sitting on

6条回答
  •  醉酒成梦
    2021-01-01 22:01

    I asked similar question yesterday. Here is my solution:

    Modified Authorize attribute:

    public class OptionalAuthorizeAttribute : AuthorizeAttribute
    {
        private class Http403Result : ActionResult
        {
            public override void ExecuteResult(ControllerContext context)
            {
                // Set the response code to 403.
                context.HttpContext.Response.StatusCode = 403;
                context.HttpContext.Response.Write(CTRes.AuthorizationLostPleaseLogOutAndLogInAgainToContinue);
            }
        }
    
        private readonly bool _authorize;
    
        public OptionalAuthorizeAttribute()
        {
            _authorize = true;
        }
    
        //OptionalAuthorize is turned on on base controller class, so it has to be turned off on some controller. 
        //That is why parameter is introduced.
        public OptionalAuthorizeAttribute(bool authorize)
        {
            _authorize = authorize;
        }
    
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            //When authorize parameter is set to false, not authorization should be performed.
            if (!_authorize)
                return true;
    
            var result = base.AuthorizeCore(httpContext);
    
            return result;
        }
    
        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            if (filterContext.RequestContext.HttpContext.Request.IsAjaxRequest())
            {
                //Ajax request doesn't return to login page, it just returns 403 error.
                filterContext.Result = new Http403Result();
            }
            else
                base.HandleUnauthorizedRequest(filterContext);
        }
    }
    

    HandleUnauthorizedRequest is overridden, so it returns Http403Result when using Ajax. Http403Result changes StatusCode to 403 and returns message to the user in response. There is some additional logic in attribute (authorize parameter), because I turn on [Authorize] in base controller and disable it in some pages.

    Other important part is global handling of this response on client side. This is what I placed in Site.Master:

    
    

    I place GLOBAL ajax error handler and when evert $.post fails with 403 error, response message is alerted and user is redirected to logout page. Now I don't have to handle error in every $.post request, because it is handled globally.

    Why 403, not 401? 401 is handled internally by MVC framework (that is why redirection to login page is done after failed authorization).

    What do you think about it?

    EDIT:

    About resigning from [Authorize] attribute: [Authorize] is not only about checking Identity.IsAuthenticated. It also handles page caching (so you don't cache material that requires authentication) and redirection. There is no need to copy this code.

提交回复
热议问题