views:

106

answers:

3

Hello.

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 should 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.

A: 

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.

Chuck
So, you're saying my business layer should call the repository to validate a user? "only include navigation properties based on the user ", i don't get this bit. Can you be a little more clear? thanks
codegarten
What I meant was that, if you want to restrict things by user, you COULD exclude/include navigation properties/other properties based on the user/user type but your business/service layer is where any real logic/security should be implemented. In our situation, I extended the POCO partial class and added an IsValid bool. The code compares the returned (encrypted) password to the encrypted supplied password to determine if authentication is valid and then updates a login attempt counter. The BL decides what to do with the invalid login attempt based on other rules.
Chuck
+1  A: 

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()
        {
}
Jay
Thanks for the tips, they were useful :) But regarding the access control, i do not want my UI to be responsible for that. If i change the UI i'll lose the access control, that's why i want it to be somewhere else. My information will be accessible via web site (asp.net mvc) and REST service in the future.
codegarten
If you are going to have multiple interfaces in the future I would strongly suggest adding a "Services" layer in between your UI and BL. this will help in the future for you to switch around or add multiple UIs. You can just move this authorization logic into a WCF Services layer in that case. There are a bunch of articles on this as well. Hope this helps :)
Jay
A: 

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.

Tiendq

related questions