Today I started working on the security layer of a web application. I won’t divulge the details of what I’m working on, but we can call it PaymentSystem.
One of the requirements of this project is to hook into an old database. The company is still using applications that use this data, and it’s not going to be changed for a few years. Because it will be merged with a larger corporate database in the future, I have to maintain flexibility.
I took a look at the database to figure out what was going on with authentication. I discovered that there can be only one role per user, the passwords are encrypted, etc. I decided at that point to tackle the RoleProvider first.
A few google searched yielded some good resources, and a few hours later I had my custom RoleProvider. Here are the resources I used:
http://msdn2.microsoft.com/en-us/library/ms998314.aspx
http://msdn2.microsoft.com/en-us/library/tksy7hd7.aspx
If you don’t feel like copying and pasting, the Joshua Flanagan has created a template file that you can install in Visual Studio. I found this after a ripped through the MSDN example, using my own DataAccess layer to simplify things.
The provider was finished, and I named it LegacyRoleProvider since it is destined for the bin in a few years. I figure whoever makes the next one can name their’s EnterpriseRoleProvider. At this stage, I have three projects in my file: the classes (compiles to dll), the website, and a testing project. I didn’t make a separate project for the provider because I wanted to utilize my DataAccess layer.
I then made a new class in my test project to hold all my unit tests for the LegacyRoleProvider. It’s pointing to a test database so I can add roles and delete roles without affecting the real application. I made my first unit test to check that a role exists, then checked it in NUnit.
PaymentSystem.Security.RoleTest.RoleExists : System.Configuration.ConfigurationErrorsException : Could not load type ‘PaymentSystem.Security.LegacyRoleProvider’ from assembly ‘System.Web, ...
What went wrong? I checked my configuration file, and I had set it up just like msdn article instructed me to do.
<
system.web>
<
roleManager defaultProvider="LegacyRoleProvider"
enabled="true"
cacheRolesInCookie="true"
cookieName=".ASPROLES"
cookieTimeout="30"
cookiePath="/"
cookieRequireSSL="false"
cookieSlidingExpiration="true"
cookieProtection="All" >
<
providers>
<
clear />
<
add
name="LegacyRoleProvider"
type="PaymentSystem.Security.LegacyRoleProvider"
applicationName="PaymentSystem"
writeExceptionsToEventLog="false" />
</
providers>
</
roleManager>
</
system.web>
I spent an hour tweaking and testing, trying to figure out what was wrong. That’s how I came across the template file, which doesn’t actually insert configuration elements for you. I was perplexed: how do you tell the this thing that the type, which clearly has a namespace different from System.Web, belongs to a different assembly than System.Web?
Luckily, I found the answer in yet another MSDN article on writing providers. You have to add a “,” and the assembly name to the type section.
type="PaymentSystem.Security.LegacyRoleProvider, PSClasses"
That goes into my book as one of those obscure, annoying problems that people rarely mention you need to do in their articles. I hope this information spares another developer an hour of his or her well-caffeinated life.