views:

283

answers:

2

I want to use the the AuthorizeAttribute to control which users are allowed access to my actions. I just want to clarify that my logic is in order.

  1. I create my own implementation of IPrincipal
  2. I post a user's credentials to a login action of a security controller.
  3. I validate the credentials with a UserService class and assign the IPrincipal returned from my UserService class to HttpContext.User
  4. My WebAuthorizeAttribute, which inherits AuthorizeAttribute, checks the current HttpContext.User.Identity.IsAuthenticated and HttpContext.User.IsInRole to determine if the user has access to the action.

Is the the normal flow of things? I know I could inherit MembershipProvider, but I don't need all of the functionality there, really just the ability to login with two different roles.

+3  A: 

You'll have to store IPrincipal somewhere and restore it with every request. If you'll use FormsAuthentication, this is good solution:

ASP.NET 2.0 Forms authentication - Keeping it customized yet simple

you can find other solutions here:

http://stackoverflow.com/questions/1821412/where-to-store-logged-user-information-on-asp-net-mvc-using-forms-authentication/1821560#1821560

and propably in many other StackOverflow questions:)

EDIT

About MyBusinessLayerSecurityClass.CreatePrincipal(id, id.Name):

You should read this page:

http://msdn.microsoft.com/en-us/library/aa480476.aspx

Specially this:

The FormsAuthenticationModule class constructs a GenericPrincipal object and stores it in the HTTP context. The GenericPrincipal object holds a reference to a FormsIdentity instance that represents the currently authenticated user. You should allow forms authentication to manage these tasks for you. If your applications have specific requirements, such as setting the User property to a custom class that implements the IPrincipal interface, your application should handle the PostAuthenticate event. The PostAuthenticate event occurs after the FormsAuthenticationModule has verified the forms authentication cookie and created the GenericPrincipal and FormsIdentity objects. Within this code, you can construct a custom IPrincipal object that wraps the FormsIdentity object, and then store it in the HttpContext. User property.

FormsIdentity is managed automatically after you set authentication cookie. All you have to do is wrap it up in your IPrincipal. All this happens when HttpContext.Current.User property is not null (it is GenericPrincipal, which you replace shortly after). When HttpContext.Current.User is null then there was no authentication cookie created earlier and user is not authenticated.

LukLed
I've read a lot of the questions and outside blogs but none really seem to put this whole part into context.
scottm
could you explain the MyBusinessLayerSecurityClass.CreatePrincipal(id, id.Name) portion. i don't understand how you get a FormsIdentity if the the HttpContext.Current.User property is null.
scottm
+2  A: 

I believe the following is more typical:

  1. I create my own implementation of IPrincipal
  2. I post a user's credentials to a login action of a security controller.
  3. I validate the credentials with a UserService class and construct a cookie that has some identifying information for this user. Typically FormsAuthentication.SetAuthCookie or some combination of that class's utility methods are used.
  4. In the Application AuthenticateRequest event, inspect the cookie and assign Context.User. Note: This value is automatically assigned to Thread.CurrentPrincipal after the AuthenticateRequest event. This is a one-time assignment and these values are not automatically synchronized thereafter.
  5. My WebAuthorizeAttribute, which inherits AuthorizeAttribute, checks the current HttpContext.User.Identity.IsAuthenticated and HttpContext.User.IsInRole to determine if the user has access to the action.
gWiz
+1: That is what I do too. My post explains how to inspect the cookie.
LukLed
excellent, thanks for the input
scottm

related questions