Wednesday, May 31, 2006

Update: Custom Membership Provider

Yep, it was just that easy. It took me a total of 2 hours to write and test a custom provider that would solve the hack problem I wrote about last time. It would take longer if you wanted to implement a full provider, but I only needed CreateUser and DeleteUser for this issue.

The documentation and examples for creating a membership provider are good, so there's no need to cover the basics. I did run into a couple of gotcha's.

First, I really didn't need total customization so I simply extended the Framework's SqlMembershipProvider. If you are using SqlServer, this works fine. The strange thing here is that the connection string, _sqlConnectionString in the provider, is private. This being the case I had to override Initialize and get the value for myself before passing the config along to the base class. Not difficult, just a silly repeat of existing code in the base.

My only other issue was with providing a good message to users if my custom provider Create or Delete operations gave an exception. The basic model on Create is to trap significant issues and log the specific problem while returning null as the MembershipUser and setting the
MembershipCreateStatus to some error type. In this case, the only applicable status is 'ProviderError' which causes a generic message to be displayed to the user. Logging isn't really helpful in this case, so I wrote the real message to a Session variable on the current HttpContext. OnCreateError, i set the error message to this session value.

Otherwise, all I really did was move my code from the OnUserCreated method into the Create method of my new provider. Wired this provider up instead of the other one, and viola!

Hats off to MS on this strategy implementation.
Submit this story to DotNetKicks


James Dunne said...

Exactly which classes did you inherit from for the custom MembershipProvider and what does the membership etc. section in Community Server's Web.Config look like?

If I try to inherit from SqlMembershipProvider I get:

Unable to cast object of type 'MyCustomProvider' to type 'Microsoft.ScalableHosting.Security.MembershipProvider'.

gabe19 said...

I created a new assembly with a class that inherits from System.Web.Security.SqlMembershipProvider in the 2.0 version of the framework. I changed the "membership" section of web.config --

<membership defaultProvider="MySqlProvider"><providers><clear /><add.../></providers></membership>

This all then occurred in my site, outside of CS. The issue here was to login to a site outside of CS that would drop a cookie that CS would recognize, and which would allow users to be created on one and recognized at the other.