views:

127

answers:

1

I'm building an ASP.NET MVC site where I want to use DotNetOpenAuth to implement OpenID login (I'm completely dropping username/password-based login).

So far, I've been writing my code for the default username/password system with the ASP.NET Membership Provider, utilizing the roles system, the profile system, and the basic registration system. Now, in my migration to OpenID, I'm foreseeing some issues, specifically with interfacing with membership controls provided by the ASP.NET Membership Provider.

Looking at the DotNetOpenAuth MVC sample, I see that the only references to the FormsAuthentication system are to create an AuthCookie and later to call FormsAuthentication.SignOut(). Thus, I'm not sure whether I can use ASP.NET Membership Provider functions with this OpenID system, although another part of the sample code calls User.Identity.IsAuthenticated.


Will this OpenID system interface with the ASP.NET Membership Provider? If not, can I somehow fix that?

If the above is completely impossible, I think my next course of action would be to just roll my own database tables and manually write the code to use them from my Account controller. I noticed that the Stack Exchange Data Explorer takes this approach, but would this be the right course of action?


EDIT: Just to be sure I'm using the correct terminology, by "ASP.NET Membership Provider", I mean the provider that uses the tables generated by the aspnet_regsql.exe tool.

+4  A: 

They will interface just fine, but you will need to do a bit of custom work.

What I have done in the past is this:

First I'm assuming you have a semi working openid implementation, meaning you can receive the actual identity from an openid provider but just not sure what to do with it.

I continue to use FormsAuthentication as a back end even without using it for Authentication.

You will need a database table that allows you to tie a FormsAuthentication user to one or more openids. You can simply store the FormsAuthentication username (which doesn't exist yet) with the identity URL you receive from the openid provider. We'll call this table AUTH

When someone authenticates to your site with an openid check whether it exists in the AUTH table. If not you need to do two things. Call Membership.CreateUser() passing in whatever generated username you want (or the email address if provided by openid). I user a GUID for the password since it won't be used. At the same time put an entry in the AUTH table mapping the Membership username to the openid claimed identity.

When someone authenticates to your site with an open id and it already exists call FormsAuthentication.RedirectFromLoginPage with the username associated with the openid and all the appropriate authentication tickest will be set.

Now you can use all the nice built in security objects just like you always could before implementing openid.

EDIT: As an added benefit of this setup you have the option in the future of allwoing username/password logins.

You can also swap out your membership provider at any time.

Also, the many to one nature of the AUTH table allows you to easily associate multiple openids.

jwsample
Wonderful answer - will implement this today. Thank you *so* much!
Maxim Zaslavsky
And I can still use `Membership.GetUser()`, right?
Maxim Zaslavsky
Yes, you can still use Membership.GetUser().As soon as you pass the username to RedirectFromLoginPage you are essentially equal to what would have happened through the built in login controls.
jwsample