是否为每个请求调用 OnAuthorization?

Is OnAuthorization called for every request?

问题:是否为每个请求调用 OnAuthorization?如果没有,我在哪里可以检查会话超时 before Authorize attributes are called?

背景: 我需要一种方法来确定会话是否存在并且没有超时。我想在我的应用程序中的每个控制器的每个方法调用上执行此操作。我需要在调用授权过滤器之前执行此操作,因为我在会话中保留了一个哈希权限集,并且我的授权属性查看这些权限。无论是否应用授权属性,我都需要为每个请求执行此操作。

我读过的几个答案(下面引用了一个)指出要覆盖基本控制器中的 OnActionExecuting。这是有道理的,但是我发现直到调用过滤器属性中的 AuthorizeCore 之后才调用 OnActionExecuting 。

到目前为止,我采用的方法是检查基本控制器中的会话并检查授权属性中的权限。

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);
        //}
    }
}

参考资料

When OnAuthorization method is called?

With ASP.NET MVC redirect to login page when session expires

也许以下适合您,将其添加到 Global.asax

protected void Application_AcquireRequestState()
{
    if (Context.Session!=null && Context.Session.IsNewSession)
    {
        //do something
    }
}