Whidbey asp.net membership api
Microsoft released a back port of the Whidbey membership api that is available here. I dug into this with great anticipation for an upcoming project and really thought it would be just the ticket for my upcoming web application needs. I had a number of reasons to be optimistic. I had dinner with Scott Guthrie “way back” at the 2003 PDC and talked about this api and sat through his presentations at PDC. After some followup email, I determined that some of the missing features, such as account lockout would be part of the api. I have used a derivative of the original IBuySpy since our early release and though the Forms Authentication apis were a pretty good start, I assumed that the new code would be an incremental improvement over that original base.
Well I was partly correct. The api and those sorts of things you should always think about when doing web security are well represented in the interfaces and the provided SqlMembershipXXXX classes. Account lockouts, user information, a flexible state collection of attributes, roles, login, user online features and much more are present. Good, that is what I expected. What's really new is that all of these things are provided to the execution context automatically by configuration, where in the past you had to wire up these things, much of it on your own, in Global or some suitable alternative. The design does seem to correctly abstract a lot of this stuff out and make it easier to plug in just what's unique to your application.
Hopefully I have thrown enough positives to keep you reading through the rest, because in the end, I am not sure how I can use this at all. The problem, at least as it stands with the current back ported code drop and all it's associated disclaimers about future api changes, the problem is that nasty “let me configure a static instance for you” type of solution that so often just doesn't work. DAAB for example which has now been largely rewritten is a good example. What's the problem?
OK, in my world, I have many different types of authentication stores and I think most people are in a similar situation. So, I have user information in Active Directory for internal users. I have a contact system that contains user profile information about one class of customers. I have a variety of different databases containing user credential information that vary depending on many factors, but when they were developed is the most common one. Roles are another story. Roles are determined along a chain of decisions from different sources. Portal configuration, active directory groups, application configuration, application logic all have a place in determining roles for a user. The point is that many enterprises contain users in a wide variety of information stores each of which has it's own nuances for connection, validating and retrieving identity information. And, you don't know the full story until you get some input from the user. This is after the new membership IHttpHandler has already wired up your provider. And after it's wired up, it's a static that can't be changed because it's read only. If it could be changed, it wouldn't work, because it can't be substitute for one user without affecting another. I even spent some time building a custom Provider, thinking that as the request started, I could decorate the actual provider needed and delegate away. Even that doesn't work. If I set a class level “RealProvider“ for my thread, either the next guy will either have the wrong provider or I will have the wrong provider. That leaves me with having to use a delegate for each method on the interface. But wait, the problem is the same, change the delegate for call one, call 2 comes in and changes it for themselves. The only thing that can work is to make changes in local variables that will be tied to the thread. Even with that, the only context you get to determine what to do is the parameters passed to the method such as username and password. Sometimes that would be enough, but many times it's just not enough to determine what provider to go against.
There was a belief that at some point ldap directories would change all this, but in every place I have ever worked, the implementation of that has always slipped to the back burner. I don't see adoption of Active Directory Application Mode changing that. There is a fundamental assumption about the world that I think has proven to be wrong there. It's the Passport vs Liberty alliance argument. Should the world look to one repository to hold all authentication and profile data, or should this be federated by design, with good techniques to move information between them. I think that while a single repository approach would be much simpler to implement if it were actually possible, the world has answered by default: there will always be many different repositories of user credentials and profile information. Deal with it.
I would really love for somebody to enlighten me as to the error of my ways, my total lack of understanding of how it works, ways to work around it. Until then, I am back to rolling my own solution. A coworker Chad (sorry he doesn't blog so no link) made an observation about IBuySpy that has stuck with me. What is really so powerful about it is not what it does provide, but that it didn't provide too much, and still has a structure that is really easy to build on. In the case of authentication and authorization, we had to roll some of it on our own, but were able to do so in the face of multiple authentication stores, and do it with minimal lines of code.
This regularly scheduled coding session will resume where it left off.....