ASP.NET Role Provider Visual Studio template
Of all the new providers that ASP.NET 2.0 introduces, I think the RoleProvider will be the most frequently implemented in a corporate IT environment. Intranet applications can usually take advantage of Windows integrated authentication for user identification. By default, this will create a WindowsPrincipal object that contains all of the user's domain groups as roles to be used for authorization. However, it has been my experience that most applications do not use domain groups for their role-based authorization. It is more likely that they have a database (or some other store) that associates a user's Windows login name with application specific roles.
In the past (.NET 1.x), you could get around this by hooking into the HttpApplication.AuthenticateRequest event (via Global.asax or an IHttpModule). You would lookup the user's roles in your data store, initialize a GenericPrincipal with the roles, and then use it to replace the WindowsPrincipal on the current thread*.
This process is greatly simplified by the introduction of the RoleProvider framework, which is already hooked into the request processing lifecycle by way of the RolePrincipal class. This means you no longer need to manually hook into an application event or create a custom principal, just to set the user's roles. The provider model allows you to focus your code on the singular task of retrieving the roles for a user.
The biggest drawback to the new approach is that the contract for a RoleProvider is pretty extensive. In addition to the large number of methods that must be implemented, there are additional "expected implementation details" that the signatures do not cover (a topic recently discussed by K. Scott Allen).
The good news is that these implementation details have been thoroughly documented in a white paper on MSDN. The bad new is that because of the wealth of information, you will probably find yourself needing to re-read that paper every time you try to implement a new provider.
That is exactly the problem I am trying to solve by introducing my ASP.NET RoleProvider Visual Studio template. Download the zip file, save it or rename it so it has a .vsi exentsion, run it, and accept the prompts (and warnings - sorry, I did not sign the code**). You will now have a new option when adding a new file to a project.
Just name the file, and a class with that name will be added to your project. The class inherits from RoleProvider, and has a stub implementation for all of the methods so it can immediately compile. At the very least, you will need to modify the GetRolesForUser() method, and take a look at each section marked with a TODO: comment. Most of the other remaining methods will just throw a NotSupportedException. This is actually a legitimate implementation for many scenarios, as you may not need the additional functionality of the RoleManager. However, if you do want to implement a full solution, the whitepaper guidance for each method is included as comments. If you find the guidance comments distracting, I provided instructions on how to do a quick find/replace to delete them all.
I plan to create additional templates for the other common provider types, but I would like to get some feedback first. I want to know if people find this helpful. How could it be better? The biggest thing I struggled with is how much documentation to include. I always get a little overwhelmed when I add a new file, thinking I'm starting fresh, only to be presented with a bunch of code or comments. It creates the feeling that the person has to read and understand it all before they modify anything. I tried to put focus on the parts that matter (with the TODO comments, and calling out the main method GetRolesForUser). What do you think? Should there be more guidance comments, or less? Should I include the XML Documentation comments for each method, copied from MSDN?
Download the installation file here and provide feedback in the comments below.
* For a few more details on the 1.x approach, check out this article on FormsAuthentication. Step 4 is the relevant part, and works just as well for Windows authentication (use the WindowsIdentity instead of FormsIdentity).
** If you do not trust the automatic installation, you can perform a manual install. Keep the file extension from as .zip and extract the contents (a .vscontent file that you can delete, and 2 .zip files). Copy the 2 zip files to your user item templates folder - the "Visual Studio user item templates location" setting in the Projects and Solutions | General tab of the Visual Studio 2005 options dialog.
Comments
I like the trace helper too. A useful addition would be to write out parameter names and values.
Making a generic trace function that outputs the parameter values is a little trickier than the current implementation. The values are not available via reflection (that I know of - let me know if you find differently), so you would have to pass the parameter values into the trace method.
The signature would look something like this:
private void traceMethodCall(params object[] args)
and the method calls would look like:
public override bool IsUserInRole(string username, string roleName) {
traceMethodCall(username, rolename);
public override bool RoleExists(string roleName) {
traceMethodCall(roleName);
So, not as easy to just copy & paste the funciton call into every method.
If you're interested in the full implementation, I could throw the code together for a post.
Thanks!
I'm not criticizing your article on excluding information about provider configuration. I had a problem, and I wanted to write about my experience in case someone else has the same problem.
Great job on the template, btw.