Question: Is OnAuthorization called for every request? If not, where can I check for session timeout before Authorize attributes are called?
Background: I need a way to determine if session exists and has not timed out. I want to do this on every method call for every controller in my app. I need to do this before authorization filters are called because I keep a hashset of permissions in session and my authorize attribute looks at these permissions. I need to do this for every request, regardless of whether an authorize attribute is applied or not.
A couple answers I've read (one cited below) state to override OnActionExecuting in a base controller. This makes sense however I've found OnActionExecuting is not calleed until after AuthorizeCore in the filter attribute is called.
The approach I've arrived at thus far is to check for session in a base controller and check for permission in an authorize attribute.
BaseController.cs:
protected override void OnAuthorization(AuthorizationContext filterContext)
{
// This base does two things:
// 1.) Ensures that Session exists
// 2.) Ensures that the Security object exists and is initalized.
HttpContextBase httpContext = filterContext.HttpContext;
// Check if session exists
if (httpContext.Session == null)
filterContext.Result = Redirect(core.SecurityConstants.SessionTimeoutRedirectURL);
else
{
if(!Security.IsInitialized())
filterContext.Result = Redirect(core.SecurityConstants.PermissionDeniedRedirectURL);
else if (httpContext.Session.IsNewSession) // check if a new session id was generated
{
// If it says it is a new session, but an existing cookie exists, then it must have timed out
string sessionCookie = httpContext.Request.Headers["Cookie"];
if ((null != sessionCookie) && (sessionCookie.IndexOf("ASP.NET_SessionId") >= 0))
{
if (httpContext.Request.IsAjaxRequest())
{
filterContext.HttpContext.Response.StatusCode = 401;
httpContext.Response.End();
}
filterContext.Result = Redirect(core.SecurityConstants.SessionTimeoutRedirectURL);
}
}
}
base.OnAuthorization(filterContext);
}
SecurityAttribute.cs:
public class SecurityAttribute : AuthorizeAttribute
{
public Permission Permission { get; set; }
public SecurityAttribute(Permission permission)
{
Permission = permission;
}
protected override bool AuthorizeCore(HttpContextBase httpContext)
{
base.AuthorizeCore(httpContext);
return Security.HasPermission(Permission);
}
protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
base.HandleUnauthorizedRequest(filterContext);
//if (filterContext.RequestContext.HttpContext.User.Identity.IsAuthenticated)
//{
filterContext.RequestContext.HttpContext.Response.Redirect(SecurityConstants.PermissionDeniedRedirectURL);
//}
}
}
References
When OnAuthorization method is called?
With ASP.NET MVC redirect to login page when session expires