ASP.Net MVC how to determine if a user can access a URL?

asp.net-mvc, authorization

Solution

What is the problem you are trying to solve? It sounds like you may be headed down a path to a complex solution that could use a simple solution instead.

If a user doesn't have permissions to access the page after login, are you wanting non-logged in users to go to one page, while logged in users go to a different page?

If that's the case I might be tempted to create another controller for just such scenarios and redirect to that controller anywhere the user doesn't have access. Or if you are using your own base Controller I would put the functionality there.

Then the controller could present the desired view. For example if a non-logged in user tries to access a page they could get redirected to a generic error page. If the user is logged in, they could get redirected to a not authorized page.

This is very similar to Robert's answer.

Here's a basic skeleton for a base controller.

public BaseController: Controller
{

... // Some code

    public ActionResult DisplayErrorPage()
    {
        // Assumes you have a User object with a IsLoggedIn property
        if (User.IsLoggedIn())    
            return View("NotAuthorized");

        // Redirect user to login page
        return RedirectToAction("Logon", "Account");
    }

}

Then in lets say a AdminController (that inherits from BaseController) action

public ActionResult HighlyRestrictedAction()
{
    // Assumes there is a User object with a HasAccess property
    if (User.HasAccess("HighlyRestrictedAction") == false)
        return DisplayErrorPage();

    // At this point the user is logged in and has permissions
    ...
}

Problem

So I was reading another question regarding login loop when you have a user logging in, set to return to a URL which they might not have access to after logging in (ie. an admin page, and the user logs in with a normal account). The solution under WebForms seems to be to utilize the `UrlAuthorizationModule.CheckUrlAccessForPrincipal` method. However that does not work for URLs going to Action Methods secured with the Authorize Attribute. I figured I could work out which method the URL was pointing at and reflect over it to solve my problem - but I can't seem to work out how I get this information out of the routing table. Anyone ever worked with this, or have a solution for this? If I can just get hold of the route information from a URL I think I could work the rest out, but if anyone has a generic solution - ie. some hidden method akin to the before mentioned one for MVC, then that would be totally awesome as well. I'm not asking how to check if the User has acces to a specified Controller/Action pair. I first and foremost need to work out how to get the Controller/Action pair from the RouteTable based off the URL. The reason for all the background story, is in case that there does indeed exist an equivalent to `UrlAuthorizationModule.CheckUrlAccessForPrincipal` for MVC.

Original source