1

I have a requirement for a new ASP.NET MVC application. When a user is logged into the site there is a black box that we need to call into to see if the user is allowed to use the Controller/Action.

All our controllers have the [Authorize] attribute by default (except Login), but some of the actions can only be called if a black box says the user can.

How would I get the MVC sub system (I'm guessing thru something like a custom [Authorize?]) to respond with an unauthorized response when a logged in user tries to access a Controller Action which the black box says they can't.

Here's the way we call the BlackBox:

 bool canAccess = BlackBox.HasAccess(controllerName, ActionName, userGuid);

2 Answers 2

2

I suggest a custom Authorize attribute (as you already guessed).

Here is an example below:

public class BlackBoxAuthorizeAttribute : AuthorizeAttribute
{
    protected override bool AuthorizeCore(HttpContextBase httpContext)
    {
        bool authorized = base.AuthorizeCore(httpContext);

        if (authorized)
        {
            var routeData = httpContext.Request.RequestContext.RouteData;
            var controller = routeData.GetRequiredString("controller");
            var action = routeData.GetRequiredString("action");

            bool canAccess = BlackBox.HasAccess(controller, action, userGuid);

            if (!canAccess)
            {
                httpContext.Items["BlackBoxError"] = true;
                return false;
            }

            return true;
        }
        else
        {
            return authorized;
        }
    }

    protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
    {
        bool blackBoxError = filterContext.HttpContext.Items["BlackBoxError"] != null && Convert.ToBoolean(filterContext.HttpContext.Items["BlackBoxError"].ToString());

        if (blackBoxError)
        {
            //change the controler name and action name accordingally as needed.
            filterContext.Result = new RedirectToRouteResult(new RouteValueDictionary
                                                                        {
                                                                            { "controller", "Error" }, 
                                                                            { "action", "BlackBoxError" } 
                                                                        }
                                                                    );
        }

        base.HandleUnauthorizedRequest(filterContext);
    }
}

With this in place you'll have to replace all AuthorizeAttribute annotations with BlackBoxAuthorizeAttribute. Or even better: remove AuthorizeAttribute from your controllers and register a global attribute in app_start.

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
        {
            filters.Add(new BlackBoxAuthorizeAttribute());
        }

Hope this helps!

Regards, Uros

Sign up to request clarification or add additional context in comments.

1 Comment

And what if BlackBox is not a static? That's tight coupling which seems a bit problematic...
0

You can try inheriting from AuthorizeAttribute and create you own attribute.

public class BlackboxAuthorizeAttribute : AuthorizeAttribute
{
 protected override bool AuthorizeCore(HttpContextBase httpContext)
 {
 //write here custom authorization logic
 }
 protected override void HandleUnauthorizedRequest(System.Web.Mvc.AuthorizationContext filterContext)
 {

 }
}

And then use your custom authorize attribute on your controller action.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.