Perhaps one of the most ubiquitous means of user management in an ASP.NET application is the oft-maligned Membership library, but let's be honest; the default Membership tools suck. If you use the default
Profile providers, you're going to have the awesome privilege of dealing with a database schema that revolves around serializing user information to
Fortunately, you can use the provider model AND still maintain a sane, usable database schema; especially helpful when trying to integrate with an existing user store. And how do we accomplish this minor miracle? Well, I'm glad you asked!
See, it's easy to forget sometimes that a lot of the classes we use as part of the .NET framework are not sealed, which means we can extend their functionality through inheritance, or (in the case of abstract classes like
MembershipProvider) implement our own derived classes, which can then be plugged into any library that is built to accept the base type as a parameter or property. This is especially true of ASP.NET and the provider model. For this post, I'm going to cover how we can implement a custom
MembershipProvider, and touch on how it integrates with my preferred method of authenticating users,
First, let's look at the code you need for a custom provider, and then I'll explain what still needs to be done:
Amusingly, most of the methods that are defined in a
MembershipProvider are not actually necessary if you don't plan on using FormsAuthentication beyond simply authenticating users. More than a few older tutorials might include something like
Membership.ValidateUser(userName, password) within a login page; if you want that to work, you need to implement the
ValidateUser() method in your custom provider. Pretty much everything else is done using the FormsAuthentication object;
FormsAuthentication.CreateAuthToken(userName, false) and
FormsAuthentication.SignOut() more or less handle signing a user in and out of your application.
What YOU Need to Do
The code above is the basic shell you'll need to create a custom Membership provider. To make it work, you'll need to add or amend the
<membership> section in your web.config so that ASP.NET knows to use your provider. It should look similar to this:
<membership defaultProvider="CustomMembershipProvider"> <providers> <clear /> <add name="CustomMembershipProvider" type="Fully.Qualified.Namespace.CustomMembershipProvider" connectionStringName="YourConnectionStringName" enablePasswordRetrieval="false" enablePasswordReset="true" requiresQuestionAndAnswer="false" requiresUniqueEmail="true" maxInvalidPasswordAttempts="5" minRequiredPasswordLength="6" minRequiredNonalphanumericCharacters="0" passwordAttemptWindow="10" applicationName="/" /> </providers> </membership>
You also need, at a minimum, to add code to the
ValidateUser() method to query your data store for a user matching the provided credentials.
Quote of the Moment
A programmer is a person who passes as an exacting expert on the basis of being able to turn out, after innumerable punching, an infinite series of incomprehensible answers calculated with micrometric precisions from vague assumptions based on debatable figures taken from inconclusive documents and carried out on instruments of problematical accuracy by persons of dubious reliability and questionable mentality for the avowed purpose of annoying and confounding a hopelessly defenseless department that was unfortunate enough to ask for the information in the first place.