Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / ASP.NET / General / December 2007

Tip: Looking for answers? Try searching our database.

Implementing a Custom Membership Provider

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Jonathan Wood - 07 Dec 2007 01:08 GMT
Although this will be a challenge at my level of ASP.NET knowledge, I'm
thinking I should implement my own membership provider class.

Looking over the methods I must implement, a number of questions come to
mind.

1. How would one implement GetNumberOfUsersOnline? I'm not sure where there
is any indication of this? And it this affected by the "Remember me next
time" checkbox, which doesn't seem to work like it does on any other site
I've seen.

2. If I want to be able to provide a user password in response to the user
answering their private question, how would I best store the password? I
understand the default encryption cannot be unencrypted, but suspect that no
encryption at all is not the best approach.

3. I see that the ASP.NET SQL membership provider uses uniqueidentifier for
the primary key for each user. Is there any particular reason to use this
type instead of an automatically incrementing integer? Any downside to using
integers?

I'd appreciate any tips with respect to any of these issues.

Thanks!

Signature

Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com

Registered User - 07 Dec 2007 02:19 GMT
>Although this will be a challenge at my level of ASP.NET knowledge, I'm
>thinking I should implement my own membership provider class.
[quoted text clipped - 6 lines]
>time" checkbox, which doesn't seem to work like it does on any other site
>I've seen.

I just looked at some 1.1stuff I wrote and GetNumberOfUsersOnline
method throws a NotSupportedException. At best the return value will
be a snapshot of an estimate, just a meaningless number. There was
just no reason to implement the method.

>2. If I want to be able to provide a user password in response to the user
>answering their private question, how would I best store the password? I
>understand the default encryption cannot be unencrypted, but suspect that no
>encryption at all is not the best approach.

There is nothing wrong with not being able to decrypt a stored
password. When a user makes the lost password request the server can
create a new password, encrypt and store a copy before sending the
unencrypted password to the user. Once the user logs in using the new
password, they can change the password to what ever they desire.

>3. I see that the ASP.NET SQL membership provider uses uniqueidentifier for
>the primary key for each user. Is there any particular reason to use this
>type instead of an automatically incrementing integer? Any downside to using
>integers?

I believe GUIDs are preferable because they can have meaning across
tables, data stores etc. When one account can have multiple
memberships, the different memberships can use the same membership ID.

regards
A.G.
Jonathan Wood - 07 Dec 2007 22:06 GMT
Registered User,

>>1. How would one implement GetNumberOfUsersOnline? I'm not sure where
>>there
[quoted text clipped - 6 lines]
> be a snapshot of an estimate, just a meaningless number. There was
> just no reason to implement the method.

I understand, but it would be useful for my application.

>>2. If I want to be able to provide a user password in response to the user
>>answering their private question, how would I best store the password? I
[quoted text clipped - 7 lines]
> unencrypted password to the user. Once the user logs in using the new
> password, they can change the password to what ever they desire.

Right.

>>3. I see that the ASP.NET SQL membership provider uses uniqueidentifier
>>for
[quoted text clipped - 6 lines]
> tables, data stores etc. When one account can have multiple
> memberships, the different memberships can use the same membership ID.

If I implement my own provider (and I'm not sure I will), I may just use an
incrementing integer. I can't think of any problems with doing so.

BTW, do you happen to have any ideas about roles?  How would something like
Roles.GetRolesForUser() work if I implement my own provider?

Thanks.

Signature

Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com

Scott Roberts - 07 Dec 2007 23:37 GMT
>> I believe GUIDs are preferable because they can have meaning across
>> tables, data stores etc. When one account can have multiple
>> memberships, the different memberships can use the same membership ID.
>
> If I implement my own provider (and I'm not sure I will), I may just use
> an incrementing integer. I can't think of any problems with doing so.

Famous last words! ;)  I'm not going to start another "Guid vs Integer"
debate, there are plenty of those out there already. But count me in the
"Guid" camp, especially for something like membership data. You say "just
use an incrementing integer" like that is easier. In fact, it's more
difficult (only slightly). ;)

I'm curious why you want to implement your own provider. I promise not to
try to talk you out of it, I just wonder why. We "piggy back" our custom
security stuff "on top of" the standard provider and I'm fairly happy with
it. It actually adds a little "security through obscurity" since someone
familiar with the standard membership stuff won't have a clue about what
else is going on on the server after they are "authenticated" by asp.net.
Jonathan Wood - 08 Dec 2007 01:00 GMT
Scott,

>> If I implement my own provider (and I'm not sure I will), I may just use
>> an incrementing integer. I can't think of any problems with doing so.
[quoted text clipped - 4 lines]
> use an incrementing integer" like that is easier. In fact, it's more
> difficult (only slightly). ;)

I trust you'll let me know when you're in the mood for articulating the
reasons why an integer might be a problem for what I'm doing.

> I'm curious why you want to implement your own provider. I promise not to
> try to talk you out of it, I just wonder why. We "piggy back" our custom
> security stuff "on top of" the standard provider and I'm fairly happy with
> it. It actually adds a little "security through obscurity" since someone
> familiar with the standard membership stuff won't have a clue about what
> else is going on on the server after they are "authenticated" by asp.net.

I'm still unsure of the best route, especially since I'm still pretty new to
the platform. I'm not interested in being told an approach is bad, but if
you'd care to articulate what problems there might be, or what might be
better, I am very interested.

Basically, I have three types of users (roles). I need to store some basic
information for each user, plus additional information that has different
fields depending on the user's role. So I'll need the primary table with
three additional tables, which store role-specific information.

If I create my own provider, I should be able to create relationships
between the specialized tables and the basic information table. This should
allow the database to enforce the relationship so that I could never delete
user information in the basic table without also deleting the associated
specialized information. (I think--I still need to solve some details
there.)

In addition, since creating a user involves adding records to more than one
table, I could use transactions. It doesn't appear that I can create a user
with the default provider and then create a record in the secondary table
all within a single transaction.

Finally, I started wondering if it might just be easier as I seem to spend a
lot of time trying to figure out exactly how the default provider works.
I've always enjoyed creating something more than trying to figure out what
someone else has done.

I don't believe profiles would work because profile data must be the same
for each user. In addition, much of what I've read warns against using
profiles because it is inefficient.

Thanks.

Signature

Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com

Scott Roberts - 08 Dec 2007 18:16 GMT
> I trust you'll let me know when you're in the mood for articulating the
> reasons why an integer might be a problem for what I'm doing.

This debate rages on, debated by people much smarter than me. This seems
like a "fair" link to start with (be sure to click the links inside the
page, as the page itself doesn't supply too much info). Google for more.

http://www.codinghorror.com/blog/archives/000817.html

For me, the determining factor is that Guids can be created by the
application, which let's me set up all keys (both primary and foreign)
inside the application then push it all to the database in a single
transaction. I'm sure there are techniques to accomplish this with
auto-incs, but with Guids I don't need "techniques" - it's trivial.

> Basically, I have three types of users (roles). I need to store some basic
> information for each user, plus additional information that has different
> fields depending on the user's role. So I'll need the primary table with
> three additional tables, which store role-specific information.

So create your "user" table and put a foreign key to the aspnet_Users table
on "UserId". Create your role-specific tables with foreign keys to your
"user" table.

> If I create my own provider, I should be able to create relationships
> between the specialized tables and the basic information table. This
> should allow the database to enforce the relationship so that I could
> never delete user information in the basic table without also deleting the
> associated specialized information. (I think--I still need to solve some
> details there.)

You can do this anyway. The aspnet membership tables are just SQL Server
tables. There's nothing magic about them. You can add relational constraints
to them all you want.

> In addition, since creating a user involves adding records to more than
> one table, I could use transactions. It doesn't appear that I can create a
> user with the default provider and then create a record in the secondary
> table all within a single transaction.

Good point ... maybe. See below.

> Finally, I started wondering if it might just be easier as I seem to spend
> a lot of time trying to figure out exactly how the default provider works.
> I've always enjoyed creating something more than trying to figure out what
> someone else has done.

I'm with you on this one. However, I'm not sure that creating your own
Membership provider is going to accomplish that. As you've already seen, the
membership interface defines the methods that you must implement and the
built-in login controls call those methods automatically. You still have to
work within the framework that someone else built. Which means that you
still need to understand that framework. And that framework may not allow
for passing all of your custom data around easily.

For example, the "Membership.CreateUser" method doesn't provide arguments
for user preferences. So you're going to need another method call to push
the preferences to the DB. That method call isn't going to be called by the
built-in controls, so you'll have to add events to those controls to call
the additional methods. I'm not sure that you are going to be able to get
all of that to happen in a single database transaction.

IMO, the membership interface is useful for supporting non-SQL Server
databases and little else. It's a DAL, not a place for customized business
rules. If you want purely custom business rules, I'd say abandon aspnet
membership and just roll your own. It's not like it's *that* hard. The whole
point of aspnet membership was to automate and simplify a routine web site
task. For us, it made more sense to use that tool "as is" then add more
information "on top" of it.

Scott
Jonathan Wood - 08 Dec 2007 20:13 GMT
Scott,

> This debate rages on, debated by people much smarter than me. This seems
> like a "fair" link to start with (be sure to click the links inside the
> page, as the page itself doesn't supply too much info). Google for more.
>
> http://www.codinghorror.com/blog/archives/000817.html

Thanks, I'll check it out.

> You can do this anyway. The aspnet membership tables are just SQL Server
> tables. There's nothing magic about them. You can add relational
> constraints to them all you want.

Yes, I see that. For me, the issue is that now I not only need to learn all
about the ASP.NET membership interfaces, I also need a pretty thorough
understanding of the underlying tables, of which there are quite a few. It
reaches a point where whipping up something of my own almost seems easier.

Don't get me wrong though, I'd defintely prefer not to reinvent the wheel if
I don't have to. But my own implementation would be considerably simpler
than what's there and, of course, I'd understand it.

> I'm with you on this one. However, I'm not sure that creating your own
> Membership provider is going to accomplish that. As you've already seen,
[quoted text clipped - 3 lines]
> that you still need to understand that framework. And that framework may
> not allow for passing all of your custom data around easily.

So far, I'm pretty comfortable with the MembershipProvider interface. That
vast majority of the methods involved are self explanatory. And I could
simply get a reference to the provider, type cast it, and access any
additional functionality I implement.

> For example, the "Membership.CreateUser" method doesn't provide arguments
> for user preferences. So you're going to need another method call to push
> the preferences to the DB. That method call isn't going to be called by
> the built-in controls, so you'll have to add events to those controls to
> call the additional methods. I'm not sure that you are going to be able to
> get all of that to happen in a single database transaction.

I don't know what you mean by user preferences. If you are talking about
profiles, I don't see any reason to use those if I implement my own
provider. If you mean something else, perhaps you could clarify.

(BTW, for my current application, users will not create their own accounts.
They will be created by other users, such as administrators.)

> IMO, the membership interface is useful for supporting non-SQL Server
> databases and little else. It's a DAL, not a place for customized business
[quoted text clipped - 3 lines]
> web site task. For us, it made more sense to use that tool "as is" then
> add more information "on top" of it.

I just want the easiest route and can't really determine what that is right
now. Completely redoing the entire part seems like a bit more work to
me--something I'd love to take on but not now.

Thanks.

Signature

Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com

sloan - 07 Dec 2007 13:19 GMT
Here are some tidibts, not meant to be a complete answer:

1.  I think you need to write some code to keep tracked of
"LastActivityDate", and some rule that says anybody active in the last (20?)
minutes is "online".
Something like that.

2.  That is up to you....one consideration is if you want the user to be
able to recover or reset their lost password.

3.  I now prefer guid's over ints for primary keys.  It allows you (one
thing) to build relationships OUTSIDE of the database, because you're not
waiting on a return value for the SCOPE_IDENTITY.  Not that this is a
compelling reason for a MembershipProvider.
There are pros and cons of guids/uniqueidentifiers.  I guess as some level,
you just gotta pick one.  And MS picked uniqueidentifiers.

http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=404
msdn.microsoft.com/asp.net/downloads/providers/

Coding up and seeing what others have done (including this Access version)
is a good exercise.  I have yet to use Access as the Membership datastore,
but I learnt alot going through the tutorial and getting it to work.

> Although this will be a challenge at my level of ASP.NET knowledge, I'm
> thinking I should implement my own membership provider class.
[quoted text clipped - 20 lines]
>
> Thanks!
Jonathan Wood - 07 Dec 2007 22:11 GMT
sloan,

> 1.  I think you need to write some code to keep tracked of
> "LastActivityDate", and some rule that says anybody active in the last
> (20?) minutes is "online".
> Something like that.

Hadn't thought of that. Could just use a COUNT query WHERE the date is later
than 20 minutes ago.

> 2.  That is up to you....one consideration is if you want the user to be
> able to recover or reset their lost password.

That was the consideration I raised. But storing an unencrypted password is
less than ideal as well. I wasn't sure if there was a medium security
approach where perhaps I could decrypt the password. Otherwise, I'll just
have to reset it.

> 3.  I now prefer guid's over ints for primary keys.  It allows you (one
> thing) to build relationships OUTSIDE of the database, because you're not
> waiting on a return value for the SCOPE_IDENTITY.  Not that this is a
> compelling reason for a MembershipProvider.
> There are pros and cons of guids/uniqueidentifiers.  I guess as some
> level, you just gotta pick one.  And MS picked uniqueidentifiers.

Right.

> http://imar.spaanjaars.com/QuickDocId.aspx?quickdoc=404
> msdn.microsoft.com/asp.net/downloads/providers/
>
> Coding up and seeing what others have done (including this Access version)
> is a good exercise.  I have yet to use Access as the Membership datastore,
> but I learnt alot going through the tutorial and getting it to work.

Okay, thanks for the links.

BTW, do you happen to have any ideas about roles?  How would something like
Roles.GetRolesForUser() work if I implement my own provider?

Thanks.

Signature

Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com

sloan - 08 Dec 2007 01:44 GMT
That's implementing a custom Role Provider.

Same concept, but different abstract class.

Google
Custom Role Provider

or check out
http://msdn2.microsoft.com/en-us/library/tksy7hd7.aspx

> sloan,
>
[quoted text clipped - 37 lines]
>
> Thanks.
Jonathan Wood - 08 Dec 2007 20:13 GMT
Ah, should've guessed! ;-)

Thanks.

Signature

Jonathan Wood
SoftCircuits Programming
http://www.softcircuits.com

> That's implementing a custom Role Provider.
>
[quoted text clipped - 47 lines]
>>
>> Thanks.

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.