手动触发授权验证

Trigger authorization validation manually

我的网站上有一个自定义 AuthorizeAttribute。它有一些关于为未经批准的请求创建的 Result 的逻辑。

在某些情况下,我想手动触发其验证*。我不知道是否可能。由于我还没有找到如何做到这一点,我认为我可以提取逻辑以将 Result 获取到不同的方法,并在需要时调用它。但是后来我不知道如何执行 ActionResult (在 de controllers 之外)。

如何手动执行授权验证?如果不可能,我该怎么做才能在控制器外部执行 ActionResult?

*我需要手动触发,因为有些请求可能会通过验证(因为创建了session),然后在访问我的服务时,发现session被别人关闭了。我不想在 OnAuthorization 中添加对服务的调用以减少服务调用。

我不确定它是否是最好的,但我找到了一种让它工作的方法(仍在倾听更好的答案)。

  1. 当我调用服务并注意到工作会话已过期时,我所做的只是删除网络会话中的活动用户。
  2. 我的自定义授权属性还实现了 IResultFilterIExceptionFilter
  3. OnResultExecutedOnException 中,我再次验证活动用户。如果会话已删除,则应用我将在 OnAuthorization.
  4. 中应用的相同 ActionResult

这是最后的 class:

public class CustomAuthorizeAttribute : AuthorizeAttribute, IResultFilter, IExceptionFilter
{
    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        ActionResult result = Validate(filterContext.HttpContext);

        if (result != null)
            filterContext.Result = result;
    }

    public void OnResultExecuted(ResultExecutedContext filterContext)
    {
        ActionResult result = Validate(filterContext.HttpContext);

        if (result != null)
            filterContext.Result = result;
    }

    public void OnResultExecuting(ResultExecutingContext filterContext)
    {
    }

    public void OnException(ExceptionContext filterContext)
    {
        ActionResult result = Validate(filterContext.HttpContext);

        if (result != null)
        {
            filterContext.Result = result;
            filterContext.ExceptionHandled = true;
        }
    }

    public static ActionResult Validate(HttpContextBase httpContext)
    {
        if (UserActiveInSession)
            return null;

        // Different rules to build an ActionResult for this specific case.
    }
}

我没有得到 Diego 的答案,但只是简单地回答了标题,我让它像那样工作,您可以将它用作控制器操作的属性,也可以在 C# 或 Razor 视图中的任何位置手动触发它.

namespace SomeNameSpace 
{
    public class CustomAuthorizeAttributeMVC : AuthorizeAttribute
    {
        private readonly string[] rolesParams;
        public CustomAuthorizeAttributeMVC(params string[] roles)
        {
            this.rolesParams = roles;
        }

        public bool IsAuthorized { get {
                //Do your authorization logic here and return true if the current user has permission/role for the passed "rolesParams"
                string[] allowedRoles = new string[] {"role 1", "role 2", "role 3"};
                return allowedRoles.Intersect(rolesParams).Any(); //for the example
            }
        }

        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            return this.IsAuthorized;
        }

        protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
        {
            //...
        }
    }

    public class AuthorizeHelper
    {
        public static bool HasPermission(params string[] roles)
        {
            return new CustomAuthorizeAttributeMVC(roles).IsAuthorized;
        }
    }
}

用法示例:

[CustomAuthorizeAttributeMVC("role 2")]
public ActionResult SomeAction()
{
    return Content("Authorized !");
}

public ActionResult SomeOtherAction()
{
    if(AuthorizeHelper.HasPermission("role 2"))
    {
        return Content("Authorized !");
    }
    return Content("401 Not Authorized !");

}       

如前所述,它可以通过正常调用在 Razor 视图中使用

@if(AuthorizeHelper.HasPermission("role 2")) { 
     //... 
}

谢谢