Due to lack of time I haven’t been able to make a sample website showing a complete usage scenario for my NHibernate custom Membership and Role providers. However, as there are nearly 100 downloads per month and there is some people using it I’m uploading a new version. The changes from the latest release are:
Fixed an important bug that didn’t prevent locked out users from login in.
Added a CreateUserWizardEx control that allows creating a user with extra information in an easy way.
Added auto unlock support.
Fixed some minor bugs/typos.
I’ll detail a bit the new features. The standard CreateUserWizard control generates an event before creating the user (CreatingUser) and one after the user has been created (CreatedUser). Somewhere between these two events the control calls the CreateUser method of the membership provider. The CreateUserWizardEx control extends the CreateUserWizard that ship with ASP.NET 2.0. It is supposed to be used when you want to insert a user in the system without using the CreateUser method of the membership provider (for example, because you want to store more data in the database).
The CreateUserWizardEx control adds a CreateUserEx event. You should handle this event, retrieve all the information for the new user and make the insert in your users table manually (as the provider interface can’t handle extra data). This event will be generated after all the password checking and generation have been made, so you only have to insert the user in the database. When you handle this event, you’ll be passed an instance of the CreateUserExEventArgs class. This class has 3 properties: EncodedPassword, EncodedPasswordSalt and EncodedPasswordAnswer that are useful if you’re not storing the sensitive data in plain text. After the CreateUserEx event is generated, the CreatedUser event is also generated.
There is one little problem with the CreateUserWizardEx control. Because quite a bit ASP.NET classes (especially controls) haven’t been designed with extensibility in mind, it is impossible to override some of the behavior of the CreateUserWizard control to achieve the desired result. In this particular case I can’t make the control to skip the CreateUser call to the membership provider in any way without rewriting the full control (the CreateUserWizard is one of the lengthiest controls in ASP.NET this is not an option). So the only solution without compromising medium trust scenarios is to ignore the CreateUser method calls in case you plan to insert the users manually. To do this you have to set the provider attribute ignoreCreateUserMethod to true. If the CreateUserWizard control is ever rewritten with extensibility in mind this hack could be removed, but I don’t think that will happen anytime. I posted about similar lack of extensibility problems here.
The auto unlock feature is useful if you use locking. If a user fails entering the password several times in a predefined period of time (specified by the maxInvalidPasswordAttempts and passwordAttemptWindow properties) his account gets locked out. However, you need human interaction in order to unlock the user.
If the auto unlock feature is enabled, when a locked user tries to log on the system, if the data supplied is correct and a certain period of time has passed since the account was locked out, the provider automatically unlocks the account. To enable auto unlocking you have to specify enableAutoUnlock="true" in the web.config. The provider property autoUnlockMinutes controls the minium period of time to wait since the last failed login to be able to auto unlock an account. The default is 30 minutes. Note that setting this value too low can make the security benefits of having a lockout feature disappear.
I’m thinking in adding some code to enforce single user log on for the next version as time permits (don’t expect this to be implemented in 2007).
As always, feedback is welcome. As the previous version, it has been tested only in SQL Server 2005. Let me know if you try it in other databases.
You can download the providers here.