MVC3 Multi-User Data Level Security

1.2k views Asked by At

The application I am working on is multi-user and multi-company and I am having trouble at the moment trying to figure out the most efficient/best way to ensure data level security, in broad terms prevent UserA from seeing UserB's data. If there are various controllers (Products, Orders, etc) and models, then the routes are something like Product/Edit/1 and Order/Edit/1. However, to ensure that users cannot alter the routes to see each others data it seems that each service layer/db layer call will require me checking that the specific product key/order key belongs to the authenticated user? Is this the best option or am I missing something more elegant.

Edit Update

From Omri's answer below, the first link actually has a link to here. It mentions the various ways to accomplish the access level security, but I guess this is what I want to know people's opinions about. Should I do something like this:

public class ProductController
{
    public ActionResult Edit(int id)
    {
        if (_productService.CanUserEdit(id, userID))
        {
            _productService.Save(id);
        }
        else
        {
            throw UnauthorizedException;
        }

        return RedirectToAction("Index");
    }
}

OR

public class ProductController
{
    public ActionResult Edit(int id)
    {
        _productService.Save(id, userID);

        return RedirectToAction("Index");
    }
}

public class ProductService
{
    public void Save(int id, int userID)
    {
        if (CanUserEdit(id, userID))
        {
            //DO SAVE
        }
    }

    private CanUserEdit(int id, int userID)
    {
    }
}

Obviously there is not much difference between the two implementations, just whether or not the action takes place within the Controller or at the service level. The service level changes on the fly based on the company, so my guess is that we probably should do the first option and have the product service for each company derive from a common base class that implements the CanUserEdit capability since that does not change.

1

There are 1 answers

1
Omri On

Seems to be two common approaches: OnActionExecuting or AuthorizeAttribute. See here: How to Extend/Architect the ASP.NET MVC 3 Authorize Attribute to Handle This Scenario

ASP.NET MVC 3 also has Global Action Filters which allow you to apply action filters globally without the need for explicit attribute declaration: http://blog.tallan.com/2011/02/04/global-action-filters-in-asp-net-mvc-3/