So I've created a simple "hello world" in MVC as proof of concept. The index view list some made up records that are followed by the typical "edit", "details", and "delete" ActionLinks.
However, depending on which AD group owns the record, I don't render some of those options. So for example, say I'm pulling up 5 records, and I'm a member of an Group\Role that only owns 1 of them. My Index page would look something like...
Name Price
Foo1 $10.00 Details
Foo2 $20.00 Details
Foo3 $30.00 Details | Edit | Delete
Foo4 $40.00 Details
Foo5 $50.00 Details
Foo6 $60.00 Details
This all works great. The Problem is, that as a user I can just type in a URL of /Home/Edit/Foo1 and it gives me Edit access to a record I do not own.
On first search, it would seem like I am supposed to implement something called a ChildActionOnly Attribute. From what I've read, it sounds like if my controller was set to..
[ChildActionOnly]
public ActionResult Edit(string id)
{
return View(GetItem(id));
}
then it would not allow me to change my url and get there. However the moment I add that Attribute, the Action Link no longer works either.
@Html.ActionLink("Edit", "Edit", new { id = item.FooName })
I know I'm just missing something. I'm already implementing Authentication so unless you belong to the correct Role, it already blocks ALL access to that controller. However, once you have access... it doesn't mean you have access to change anything and everything.
For a more flexible approach you can create a custom
AuthorizeAttribute
for your Controller action method and then set it like this :Then with an extended version of an 'AuthorizeAttribute` you could do your check there:
This is how I like to do Authorization to AD. You can create a class property in the AuthroizeAttribute to allow you to set the user group separately for each use of the attribute as well. If you are using the authorization mechanism to control actions throughout the site I think that this is cleaner than manually performing an authorization check each time.
There's no way to prevent a user to attempting to access any URL. The client (browser) merely makes a request. It is the server's responsibility to determine whether it should return something or not.
Hiding a URL to prevent access is what's called "security by obscurity" and it's basically the same as having no security at all. There is nothing so obscure that a persistent user can't figure it out. You need real security as in role or object-level permissions tied to account authentication.
For a record, you're looking at object-level permissions. The most basic implementation involves creating a foreign key on the object to a user that represents "ownership" of that object. Then, when retrieving the object, you additionally check whether the currently logged-in user is the "owner" and if not, deny access.
First Create a class for filter: We have to call this feature under OnActionExecuting of Action filter.
Then add [PreventFromUrl] attribute to the top of your action or controller:
According to documentation:
ChildActionOnlyAttribute Class
Represents an attribute that is used to indicate that an action method should be called only as a child action.
Nkosi is right with his answer. To restrict access to this items you have to perform a user validation inside the
Edit
action. For example: