Custom Membership without using built-in provider model

K

Keith Mattson

Hi all,

I'm trying to write my own ASP.NET membership "system", and that
system does NOT derive or inherit from ASP.NET's own Membership
Provider model. I do, however, want to (more or less) "mimic" the way
that ASP.NET's membership providers work.

Whilst this may well sound like re-inventing the wheel, my reason for
doing it is this: I have tried to write a custom membership provider
that DID derive from ASP.NET's own provider model, with a class
inheriting from MembershipProvider, and another inheriting from
MembershipUser.

All I realy wanted to do was to add some simple, additional "fields"
to the user class. The major problem that I ran into was the
CreateUser method that must be overridden in your own derived class.
This method takes a series of parameters based upon the fields in
Microsoft's own "user" class. Of course, mine had additional fields,
so I could not change the methods signature to include my own fields.

Then I hit upon an idea. I decided that if I wrote my own "membership
provider" that did not derive from MembershipProvider or
MembershipUser, I could make it very generic. My idea is to have a
base class (MyMembershipUserBase) that would contain an amount of
fields that are requirements for the membership system (things like
username, password, createddate etc.).
Consumers of my "membership" system, could create thier own custom
user class, which must inherit from my base class, and could then add
thier own fields that they cared to store in the backend database.
I've even got public attributes that must decorate each field's
property accessor to inform my membership system of the relevant
database field name and datatype when persisting the new
consumer-created fields.

My own "Membership" class that contains all of the actual methods to
Create, Update, Delete (etc) user would accept parameters as my own
"base" type, and through the wonders of polymorphism and .NET's own
reflection, I would iterate through the passed in object that derives
from my own base type and figure out which new properties the
"consumer" had added, and persist those the the database (using the
attributes provided for each consumer-created property).

I was going great guns with all of this, until I remembered about such
things as IPrincipal and the forms authentication system. This is
where I'm struggling slightly. I believe that my "user" base class
should implement the IPrincipal interface, but I'm not quite sure what
code I need to put in the implemented methods from this interface.

Also, I'd like the consumer of my membership system to be able to do
things like:

HttpRequest.Current.User.Identity
HttpRequest.Current.User.IsAuthenticated
etc.

and retrieve the "custom" created user object that derives from my own
user base class (or one of it's properties). I'd like the consumer to
be able to do this without having to assign anything to
HttpRequest.Current.User themselves, however, I'm struggling with
where any assignment to to the HttpRequest.Current.User should go
within my own membership system's code.

Basically, I'd like to know how the built-in ASP.NET provider model
uses and utilises the IPrincipal interface (and possibly also the
IIdentity interface) so that I can then, hopefully, replicate that
within my own membership system code.

Anyone have advanced knowledge of how all of these things are
implemented and fit together?

Thanks in advance.


Keith.
 
N

Nicholas Paldino [.NET/C# MVP]

Keith,

I am curious, have you thought of passing your extra fields through the
providerUserKey parameter of your CreateUser implementation on the overload
of MembershipProvider? You can pass around anything you wish, so you can
make it a structure with the extra fields, and then use that to save the
information to your underlying data store.

Also, you can derive from MembershipUser and expose the properties that
you wish. Your overload of GetUser would return the derived type when
called.
 
K

Keith Mattson

Keith,

I am curious, have you thought of passing your extra fields through the
providerUserKey parameter of your CreateUser implementation on the overload
of MembershipProvider? You can pass around anything you wish, so you can
make it a structure with the extra fields, and then use that to save the
information to your underlying data store.

Also, you can derive from MembershipUser and expose the properties that
you wish. Your overload of GetUser would return the derived type when
called.

Hi Nicholas,

You know, that's a very interesting approach. I'd completely
overlooked the fact the the "providerUserKey" parameter is of type
object, so I certainly could pass around any old structure I wanted,
however, I dislike this approach for two reasons.
1) It's rather "clunky" to use the "providerUserKey" parameter to
pass around something that it was never really meant to, plus this is
something that the "consumer" of the membership system would have to
do, and it doesn't really represent a very "clean" solution (albeit
quite a clever and "sneaky" one! - If I was only doing this in
"internal" code, I may well take this approach).
2) My implementation of a "MembershipUser" class (and the
"Membership" class also) would behave slightly differently to
ASP.NET's own "Membership" and "MembershipUser" classes. I'd like for
my own "CreateUser" method to only take a single parameter, and that
would be an instance of the consumer's own "MembershipUser" class.
Since this class would be created by the "consumer" of the membership
system, and would derive from an "internal" base class of my own, it
means that the consumer need not be concerned with somewhat
restrictive method signatures (as is the case with the build-in
provider model's CreateUser method).

To be honest, if it weren't for the "CreateUser" method of the
provider's "Membership" object, I wouldn't need to do all of this, but
since this method takes a strict set of parameters, and is public in
the base class, I can't even "override" it with my own implementation
AND signature.

Any other ideas?


Best Regards,
Keith.
 
K

Keith Mattson

You might consider have your "extra fields" that don't fit into the
MembershipUser "mold" in a Profile instead. Its very easy to get the profile
data for a user. Whether or not you want to write a custom Profile provider
is of course, another question.
-- Peter
Recursion: see Recursion
site: http://www.eggheadcafe.com
unBlog: http://petesbloggerama.blogspot.com
BlogMetaFinder: http://www.blogmetafinder.com



Keith Mattson said:
Hi all,

I'm trying to write my own ASP.NET membership "system", and that
system does NOT derive or inherit from ASP.NET's own Membership
Provider model. I do, however, want to (more or less) "mimic" the way
that ASP.NET's membership providers work.

[SNIP!]

Hi Peter,

I had toyed with the idea of using the Profile provider, however, I
don't like how it stores it's data. I will ultimately need to do
various database joins and queries (including filtering) with the
"extra fields" that I'm storing, so the built-in provider
implementation (say, SqlProfileProvider) is out of the question.

I realise I could implement my own profile provider, but it seems like
a big thing to do when all I need to do is persist a "user" to my
database that contains all of the "built-in" fields, plus no more than
4-5 of my own fields, which consist of only a few strings, and ints!

Do you have any other ideas?



Best Regards,
Keith.
 
A

alexandis

Hi, Nicolas! Your idea is very attractive and my implementation is
almost done - i've created a separate class that keeps all additional
fields and it's everything ok inside extended membership provider
class, but...

how on Earth can I PASS providerUserKey object when creating new
user?? :) There's no explicit call of CreateUser method! I took a
look at CreateUserWizard control: username, password, etc. - are
passed via form fields, but what about providerUserKey?? How to assign
my object to it before CreateUser is called? Of course, it could be
some global object, but it mustn't be a global object, I guess!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,968
Messages
2,570,153
Members
46,699
Latest member
AnneRosen

Latest Threads

Top