views:

1193

answers:

4

This will be my first ASP.NET MVC application with forms authentication so I am trying to make sure I don't miss anything. The scenario is this: Public / Secured Areas.

Within the private area it is even further limited to specific areas / user. These 'Areas' are defined by customizations to the base area that is customized per user group.

So for example a user could get to url /Area/Controller/Action. They would need to have permission to the secured area or they would be redirected to the sign-in view.

I have been reading about the AuthorizeAttribute but I am not sure how/where I should be doing these basic checks. My initial hunch would be to store a user object in the session after a successful sign-in with the user's IP and details about what they have access to etc.

The authorization check for each secured controller call would verify that a valid user object exists in the session, the IPs still match up, and the user has access to the specific area. Is there any obvious holes to this setup?

Edit: Where/how do I implement these checks so that when a controller is tagged with [Authorize] it will perform those session object checks?

Any pointers or suggestions would be much appreciated. Thanks.

+1  A: 

Try to look at the RoleProvider class. This is the basic framework of how ASP.net use rolebased authorization to users. And I think you should use [Authorize(Roles='...')] attribute to make use of that.

xandy
I am trying to stay away from the baked in role solution if possible. Not sure how customizeable it is.
Kelsey
nope.. the roleprovider is the base class that you should/could implement your own customization to it. To start with custom role authorization, you just extend the roleprovider class and modify the web.config file to notify it.
xandy
A: 

In my previous application I used a simple HttpModule to augment the authenticated user with additional roles etc ( I did this because my requirements were very constrained ).

public class AuthorisationModule : IHttpModule
{
    public void Init( HttpApplication context )
    {
        context.AuthorizeRequest += AuthorizeRequest;
    }

    private void AuthorizeRequest(object sender, EventArgs e)
    {
        var currentUser = HttpContext.Current.User;
        if( !currentUser.IsAuthenticated() )
        {
            return;
        }

        var roles = new List<string>();
        // Add roles here using whatever logic is required

        var principal = new GenericPrincipal( currentUser.Identity, roles.ToArray() );
        HttpContext.Current.User = principal;
    }

    public void Dispose()
    {
        if(HttpContext.Current == null )
        {
            return;
        }

        if(HttpContext.Current.ApplicationInstance == null)
        {
            return;
        }

        HttpContext.Current.ApplicationInstance.AuthorizeRequest -= AuthorizeRequest;
    }
}
Neal
A: 

Have a look at this stackoverflow link

San
+1  A: 

Well it looks like I went with a custom AuthorizeAttribute. It was actually very simple. Here is the code:

namespace MyApp.Custom.Security
{
    public class Secure : AuthorizeAttribute
    {
        /// <summary>
        /// Checks to see if the user is authenticated and has a valid session object
        /// </summary>        
        /// <param name="httpContext"></param>
        /// <returns></returns>
        protected override bool AuthorizeCore(HttpContextBase httpContext)
        {
            if (httpContext == null) throw new ArgumentNullException("httpContext");

            // Make sure the user is authenticated.
            if (httpContext.User.Identity.IsAuthenticated == false) return false;

            // This will check my session variable and a few other things.
            return Helpers.SecurityHelper.IsSignedIn();
        }
    }
}

Then on my controllers I just have to put a [Secure] attribute and it uses my function above anytime that controller is accessed. Pretty simple. I also made a [SecureByRole] attribute as well that does all the same stuff but checks for my custom role information as well. No need to for all that built in voodoo from the canned Membership :)

Kelsey