MetaGuru
MetaGuru

Reputation: 43813

If Controller.OnAuthorization() returns void then how do I deny access?

I would have expected it to return 'true' or 'false'...

I have overridden OnAuthorization in my Controller and based on a missing or invalid HTTP Header value I want to return 403 forbidden, however I can't seem to figure out how to return anything from OnAuthorization so that it will actually stop the rest of the Controller from running.

What should I do?

My first attempt below was a huge fail, I think Deny() is running but nothing happens...

public class AuthController : Controller
    {
        protected override void OnAuthorization(AuthorizationContext filterContext)
        {
            if (string.IsNullOrEmpty(filterContext.HttpContext.Request.Headers["Authorization"]))
                Deny();

            string authString = filterContext.HttpContext.Request.Headers["Authorization"];

            base.OnAuthorization(filterContext);
        }

        private ActionResult Deny()
        {
            HttpContext.Response.StatusCode = 403;

            return Content("Access Denied", "text/plain");
        }
    }

UPDATE looks like this did the trick, any reason why this might be a bad approach?

    if (string.IsNullOrEmpty(filterContext.HttpContext.Request.Headers["Authorization"]))
    {
        filterContext.Result = Content("Access Denied", "text/plain");
        filterContext.HttpContext.Response.StatusCode = 403;

        base.OnAuthorization(filterContext);
    }

UPDATE AGAIN ok so now it's not working at all... I put in a breakpoint and watched it step INTO that if statement, and get to the base.OnAuthorization(...) call, and step right back out again... why would it go into the if statement if it was not executing? If it was executing why would calling base.OnAuthorization(...) not end things early?

Upvotes: 6

Views: 6067

Answers (5)

Venugopal M
Venugopal M

Reputation: 2412

Actually, when a controller is called for an ActionResult, the page expects a View. You could implement the following UI for the user to understand better:

//code for checking whether authorized goes here...//
bool isAuthorised = SomeFunction();
if (!isAuthorised)
{
    var viewData = new ViewDataDictionary();
    viewData.Add("Message", "You do not have sufficient privileges for this operation.");
    filterContext.Result = new ViewResult { ViewName = "Unauthorized", ViewData = viewData };
    //The View "Unauthorized" is merely a View page that could inherit from a master View or none,       
    //and could be situated in your Views\Shared folder.
    //And you can present the message in the View page like this or so: 
    //<div style="color:Red; font-size:12pt; font-weight:bold;"> <%:ViewData["Message"] %></div>
}
return;

The viewname "Unauthorized" could be any name you would like and it should be a view which resides in the Shared view folder.

Upvotes: 0

ECie
ECie

Reputation: 1477

how about using the route like this:

filterContext.Result.Result = new RedirectToRouteResult(new RouteValueDictionary(new { controller = "Message", action = "AccessDenied" }));

:)

Upvotes: 0

gw0
gw0

Reputation: 1593

What about?

throw new UnauthorizedAccessException();

Upvotes: 4

Evgeniy
Evgeniy

Reputation: 11

Another approach of securing application: Securing your ASP.NET MVC 3 Application

Upvotes: 1

Robin van der Knaap
Robin van der Knaap

Reputation: 4120

You could throw an httpexception:

throw new HttpException(403, "Access Denied");

Upvotes: 9

Related Questions