Reputation: 5157
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
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
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