Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Which tier of my ASP.NET MVC application should I be checking Membership information?

I have an MVC application which has the (simplified) structure as below (left-to-right)

UI -> CONTROLLERS -> SERVICES -> REPOSITORIES -> DATABASE

We've attempted to keep each layer decoupled from the next. We're using .NET Membership to manage security, and we have a permissions based function, let's say "Show me all documents for my user type".

Should:

  1. The Services layer have no awareness of our .NET Membership provider? We'd then have Service layer methods which looked like "GetDocumentsByUserType(int UserTypeId){ .. }"?

  2. The GetDocumentsByUserType() method be aware that we're using .NET Membership, use Membership methods to get the current user type, and return the relevant documents?

Also:

  • Does #1 make my Services layer less secure, as my controller layer
    could pass in anything it wanted as a UserType?
  • Does #2 make my Services layer too dependent on a specific technology, namely .NET
    Membership? Is there another way to consider here?

Hope I've provided enough details. Please shout if not and I'll add.

Thanks.

like image 607
christofr Avatar asked Oct 06 '11 11:10

christofr


1 Answers

You should keep all membership stuff inside the presentation (controller) layer. Suppose you ever want to add another presentation layer (or make changes to your existing layer), you'll have a hard time fixing this. Besides, you are duplicating code between your presentation layer and your services layer, which is never a good idea.

Having said this, there is no reason not to perform security checks inside your services layer but you can do this without needing to use the membership classes. First of all, the currently authenticated user is available from Thread.CurrentPrincipal (inside your service layer methods). You can use this IPrincipal to perform security checks.

Second, you can use the PrincipalPermissionAttribute to enforce security rules on your service layer methods or classes. For example:

[PrincipalPermission(SecurityAction.Demand, Role="Administrator")]
public void MySecureServiceLayerMethod()
{
    var p = Thread.CurrentPrincipal;
    ....
}

For the role stuff to work, you'd also have to use a RoleProvider implementation.

UPDATE: As Wyatt Barnett explains in a comment, using PrincipalPermission has some disadvantages. First of all, testing your code becomes more difficult. Another (larger) disadvantage is that you hard-code role names into your code. These names are usually not owned by the developer.

like image 118
Ronald Wildenberg Avatar answered Oct 21 '22 07:10

Ronald Wildenberg