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:
The Services layer have no awareness of our .NET Membership provider? We'd then have Service layer methods which looked like "GetDocumentsByUserType(int UserTypeId){ .. }"?
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:
Hope I've provided enough details. Please shout if not and I'll add.
Thanks.
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.