ASP.NET MVC4 Security, Authentication, and Authorization

asp.net-mvc-4authenticationSecurity

I'm working on a new asp.net mvc4 project using Visual Studio 2011 beta and am trying to get my head around the whole security thing. It's an internal Intranet application that will initially use single sign on, so the user will not (yet) be prompted for a Windows ID/password. The company has a custom application for storing roles for different applications and will be available via a stored procedure call. It will take a user's logon ID and return some sort of collection containing roles e.g. "MyApp.Data", "MyApp.User, "MyApp.Admin". So what is this referred to as – is this a custom Membership provider, custom Roles provider or something else?

I've been reading up on all the ins and outs of Authorization, Authentication, Membership, Roles, etc. and I can't see the wood for the trees at the moment. I've read that the existing ASP.NET Security objects have been tried and tested, and unless there are very complex requirements the in-built ones will suffice, so I'm happy to use what's already there.

So if a user is already signed in to the network this means they are authenticated – correct? If so then I just need to implement Authorization. Is it necessary to decorate each Controller or Action with the Authorize attribute? If so how does the "ABC" part of [Authorize(Roles = "ABC")] get set if I retrieve roles from my custom role storage app?

I read several articles and blog posts including this one from Jon Galloway but I got lost towards the end:

Customizing Authentication and Authorization The Right Way

So many questions…if anyone knows of good high level description of how all this hangs together then I'm all ears 🙂

Best Answer

Ok in the absence of an answer that gives a high level view of how all this hangs together I thought I'd scribble down my findings so far:

So in Global.asax I would add:

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
    filters.Add(new HandleErrorAttribute());
    filters.Add(new System.Web.Mvc.AuthorizeAttribute()); //new
}
  • Once a user is authenticated I then need to take care of Authorization. The company have an existing global data store for roles that I won't have update access to, only read access, so I can retrieve the roles for a given user via a stored proc call. It can take from a few days to a couple of weeks for the helpdesk to create roles after a request is made, so for this reason 2 standard roles will be initially created, User and Admin, and subsequent roles will be stored in our application database.

  • Along with these 2 standard roles subsequent roles are required such as Superuser, etc. These roles will have various rights depending on business rules etc. and will need to be stored in our application database. So for this scenario I will need to create a custom Role provider, add the appropriate asp.net role tables to my app database, and plug it into the web.config. Here's an ms page titled Managing Authorization Using Roles that I'm picking bits out of:

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

  • From what I've read so far the only tables I need for a custom role provider are Roles and UsersInRoles.

    CREATE TABLE Roles ( Rolename Text (255) NOT NULL, ApplicationName Text (255) NOT NULL, CONSTRAINT PKRoles PRIMARY KEY (Rolename, ApplicationName) )

    CREATE TABLE UsersInRoles ( Username Text (255) NOT NULL, Rolename Text (255) NOT NULL, ApplicationName Text (255) NOT NULL, CONSTRAINT PKUsersInRoles PRIMARY KEY (Username, Rolename, ApplicationName) )

  • Once all this is setup I need to figure out how to merge the 2 standard roles (User and Admin) from the global data store with the custom roles stored in my app database, and if I can use (e.g.) [Authorize(Roles="Admin, Superuser")] on a Controller/Action or if I need to subclass AuthoriseAttribute and do something more clever.

  • I just realised that as I use AD for authentication I need a way of adding / injecting the collection of roles the current user is a member of. So although I don't need any custom membership provider functionality I still have to interact with httpContext.User to update its Roles collection.