WhiskerBiscuit
WhiskerBiscuit

Reputation: 5157

Limiting access to MVC controllers

Assume we have a controller whose route is Project/{ProjectID:int}/Page/{PageNumber:int} This controller handles projects, each of which has an int ID, and each project has 100 pages

So project 1, page 33 would be accessed via:

http://localhost/project/1/page/33

I know I can protect access to this controller using the Authorize attribute. For example, only Authenticated users may access "project".

What are my options about protecting access to projects? Eg, Bill has access to projects (1,2,3), so he could access the controller above, but how can I prevent him from accessing?

http://localhost/project/4/page/13

Upvotes: 0

Views: 103

Answers (2)

Chris Pratt
Chris Pratt

Reputation: 239250

For strict controller level authorization, AuthorizationAttribute is the way to go, but for lower-level id authorization, I've found the best way is to simply query only for what is actually available to the user.

In otherwords, if a certain project is only available to a particular user(s) then you no doubt have a User (or similar) property on the the Project model (equating to a foreign key at the database level). Therefore, use this: when you're fetching the project based on the id, add a condition for the user as well:

var project = db.Projects.SingleOrDefault(m => m.Id == id && HttpContext.Current.Identity.Name == m.User.Username)
if (project == null)
{
    return new HttpNotFoundResult();
}

In a sense, you don't need to restrict access as much as just only make it available in the first place to the proper user.

Upvotes: 2

Ilya Sulimanov
Ilya Sulimanov

Reputation: 7836

Sure, it is better to use Authorization Attribute for this purpose. But, if you find other approach you may implement something like:

  protected void Application_AuthorizeRequest(Object sender, EventArgs e)
    {
     string userName = Request.LogonUserIdentity.Name; // Bill
     string page = Request.FilePath; //   project/4/page/    
     if !(AuthorizeUtil.CheckAccess(page, userName)
                   Context.RewritePath("/AccessDenied");     

    }

Upvotes: 0

Related Questions