手动触发授权验证

时间:2015-02-18 21:42:09

标签: asp.net-mvc authorization authorize-attribute

我的网站中有自定义AuthorizeAttribute。它有一些关于为未经过处理的请求创建的Result的逻辑。

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

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

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

2 个答案:

答案 0 :(得分:0)

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

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

    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.
        }
    }
    

答案 1 :(得分:0)

我没有得到Diego的答案,但是只是回答标题,我就可以像这样工作,您可以将其用作控制器动作的属性,也可以在C#或Razor视图中的任何位置手动触发它。 / p>

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")) { 
     //... 
}

谢谢