Search code examples
asp.net-mvcauthorizationauthorize-attribute

Trigger authorization validation manually


I've a custom AuthorizeAttribute in my website. It has some logic about the Result created for unathorized requests.

In some cases, I want to trigger its validation manually*. I don't know if its possible. As I haven't found how to do that, I thought that I could extract the logic to get the Result to a diferrent method, and call it when I want. But then I don't know how to execute the ActionResult (outside de controllers).

How can I do to manually execute authorize validation? If not possible, how can I do to execute an ActionResult outside a controller?

*I need to trigger it manually because some request may pass the validation (because the session is created) and then, when accessing my services, found that the session was closed by someone else. I wouldn't like to add a call to the services in OnAuthorization to reduce services calls.


Solution

  • I'm not sure if its the best, but I've found a way to get it working (still listening for better answers).

    1. When I call the services and notice that the work session has expired, all I do is removing the active user in the web session.
    2. My custom authorize attribute also implements IResultFilter and IExceptionFilter.
    3. In both OnResultExecuted and OnException I validate the active user once more. If the session was removed, then apply the same ActionResult that I would apply in OnAuthorization.

    Here is the final 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.
        }
    }