POCO + Entity Framework with repository pattern - permission handling
I have an application that consists of 3 layers:
UI: to be implemented in ASP.NET MVC Business: Holds the business logic and resource access control Repository (DAL): Implemented with POCO objects and EF, using the repository pattern. My POCO objects are shared with the upper layers.I have questions about what information/methods should POCOs have? i.e: if i have a User table that holds a username and password for a user, what should my POCO have? How sho开发者_如何转开发uld i validate the password? Should my POCOs have a method that asks the repository for validation?
Also, how should i control access to my resources? Should my repositories have control over who can and cannot access a resource? This still lets my POCOs expose information with navigation properties. Should i check in the POCO propoertise if the current user can use them too?
Thanks in advance.
I have a similar project and I can give you some details on how I performed similar operations. I am assuming your entire solution is .Net based.
POCO (Plain Old CLR Objects) are just that objects with no business logic. So, the password validations should not be directly in that class but in your business layer. For example, UI would call a controller action to submit the data to the Business Layer (BL), the BL would perform the user password validation by calling the repository to get the currently stored/encrypted password, BL will compare the passwords and return a result to your UI or take some other action. Of course all data should be validated as well to prevent things like SQL injection or Cross Site Scripting attacks as well.
Your POCO can have a Uid/Pwd properties. You should be passing around this POCO object betweeen your application layers. So, the MVC UI would be bound to your user object and when submitted the controller would call some method in your BL and perform and business rules (password is valid) on that user object. In order to pass these around between actual layers you need to extract those POCO's out of the main DAL and place them in a separate assembly. These objects are commonly referred to as Domain Objects and you can google Domain Driven development to get more information on that methodology.
Security can be implemented in several different ways within an application, it all depends on the depth of items that you want to cover. The most basic in MVC is to use the Authorize attribute on your controllers classes (google: Securing Your Controller Actions). When your user is authenticated they can be assigned some type of application roles and you can verify if the user has one of these roles using the following format:
[Authorize(Roles = "ModifyUserRoles")]
public ActionResult About()
{
}
If your context is returning the user object, the select would "validate" the password:
public User GetUser(string login, string password)
{
//...code to set up context var...
var user = (from o in context.Users.OfType<User>() where o.UserID == login && o.Password == password) select o).FirstOrDefault();
//...maybe more code...
}
It should be up to your business layer how to encrypt the password and how to handle a failed login (method returns null).
Personally, I don't think any business logic should be in your DAL. Determining who has access to what is a function best performed by the business layer but you could disable lazy loading and only include navigation properties based on the user OR you could make an additional request for those properties when they're needed. The amount and type of data being returned (for performance reasons) would drive that decision.
I think that it is not always necessary to pass your POCO object (domain object) through layers, for example in your situation, the View layer only need a simple View Model with just user name and password properties and passes it to BL, it is your BL who will get the User domain object via repository and validate the password against what it has received from View layer.
精彩评论