13

There are several ways to use OpenID on ASP.net sites, but none of them seem to use the existing mechanism of Membership and Authentication Providers.

I wonder what the proper way would be to create a site that solely relies on OpenID? Continuing to use Forms Authentication but implementing a variant of the SqlMembershipProvider that does the lookup against OpenID?

Or would I go one level deeper and write my own FormsAuthenticationModule? That seems to be a bit too bare-bones, as (to my knowledge) Forms Authentication can looked up against any data source.

Or is there a third way, keeping the FormsAuthenticationModule but making it do the lookup against OpenID?

As this is for an ASP.net MVC application I have no use for the built-in Login WebForms Controls if that makes a difference.

Cherian
  • 19,107
  • 12
  • 55
  • 69
Michael Stum
  • 177,530
  • 117
  • 400
  • 535

6 Answers6

10

The Membership API that ASP.NET defines doesn't fit well at all with OpenID, which is probably why you don't see many systems using it. I haven't seen a need to use the Membership provider with OpenID yet, so it hasn't really become an issue. One project that attempted to make the Membership provider model fit with OpenID is http://code.google.com/p/dotnet-membership-provider/, but it doesn't look like it's been maintained recently.

As womp said, you don't need to redo the FormsAuthenticationModule. It works perfectly well with OpenID.

Check out the project templates that come with DotNetOpenAuth to see how things can work without the membership provider.

Andrew Arnott
  • 80,040
  • 26
  • 132
  • 171
  • Vote for a better membership provider interface that works with OpenID: http://aspnet.uservoice.com/forums/41199-general/suggestions/486926-new-membership-provider-interface-supporting-redir – Andrew Arnott Feb 18 '10 at 04:19
4

The OpenID Membership Provider project might be what you are looking for.

And even though you're not using Login controls, it's still recommended to leverage the Membership Provider model for authentication.

It's not usually necessary to go as deep as implementing FormsAuthentication specific functionality, since writing a MembershipProvider is pretty trivial, and I've never found a case where it wasn't flexible enough to handle. Note that often you only need to implement one method (ValidateUser()) of the interface to get a working provider.

womp
  • 115,835
  • 26
  • 236
  • 269
  • 4
    Beware that this project is using a *very* old version of an OpenID library and is not advisable for use without upgrading to the latest version (which is DotNetOpenAuth available at http://dotnetopenid.googlecode.com/) – Andrew Arnott May 28 '09 at 19:41
2

This is an old question, but I haven't seen the approach I used when searching around for it, so here goes. (It's only tested with Google, since I'm creating the appearance of integration with my company's Google Apps for Business account, rather than full OpenID integration.)

I use DotNetOpenAuth to claim the OpenID, making sure to require the e-mail address.

        request.AddExtension(new ClaimsRequest
        {
            BirthDate = DemandLevel.NoRequest,
            Email = DemandLevel.Require,
            FullName = DemandLevel.Require
        });

Then, when I get back an authenticated response, I look up the username from the e-mail:

            case AuthenticationStatus.Authenticated:
                ClaimsResponse info = response.GetExtension<ClaimsResponse>();
                string username = Membership.GetUserNameByEmail(info.Email);
                FormsAuthentication.SetAuthCookie(username, true);
                return Redirect(ReturnUrl ?? "/");

Assuming you also have a Membership and Role provider set up, setting the forms Auth cookie for the appropriate username gives you access to all the other Membership and Roles goodness.

Dave
  • 4,375
  • 3
  • 24
  • 30
  • How do you deal with saving to the membership database? – Tadeu Maia Mar 07 '12 at 21:49
  • Saving, as in, creating new accounts? – Dave Mar 09 '12 at 14:51
  • 1
    Yes, how do you deal with passwords? – Tadeu Maia Mar 13 '12 at 20:47
  • 1
    I hadn't really thought about it. In my implementation, openID is only something they can use instead of logging in with a username and password, so they create accounts as normal. But since the password is never used, you could probably just call the appropriate memembership method to create the user with a dummy password that will never be used, setting the username and e-email address to match their OpenID e-mail address. – Dave Mar 14 '12 at 21:46
0

if anyone comes across a good c# janrain example - please let me know.

i've got dsn pointing to tumblr, then for the login widget it comes back to a subdomain where i have it's path to a folder under the root.

so then i have an app_code folder in there that i am using this c# helper class - i can get the token back just fine and it's taking me to my members.domain.com so the widget is working - just need to get the user details on the provider they used to get to the members area.

http://groups.google.com/group/rpx-developers/web/c-helper-class?_done=/group/rpx-developers%3F

is the helper class

error

Server Error in '/' Application. Unexpected API error Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Exception: Unexpected API error

Source Error:

Line 22: Line 23: Rpx feedit = new Rpx("apikey", "https://learnbartending.rpxnow.com/"); Line 24: feedit.AuthInfo(justoken); Line 25: XmlElement xmlstuff = feedit.AuthInfo(justoken); Line 26:

Source File: c:\Inetpub\vhosts\learnbartending.com\httpdocs\members\Default.aspx.cs Line: 24

Stack Trace:

Biz Brown
  • 367
  • 2
  • 8
0

If you need to leverage the userID(guid) from your Membership database then you are going to have to create a skeleton account when they first login, then figure out some mechanism of rotating a fresh password on subsequent logins. This password would obviously be for your Membership provider and would be transparent.

Now the fun part is finding metadat that is common? HMM e-mail address maybe?

I am working on this dilemma as well with facebook connect. I have to have a userid to tie them to the classified postings in my database.

Fun stuff.

Just an update. I got this working nicely.

I created a table

CREATE TABLE [dbo].[OAuthUsers]
(
    [OuthUserID] [int] IDENTITY(1,1) NOT NULL,
    [UserID] [uniqueidentifier] NOT NULL,
    [access_token] [varchar](150) NULL,
    [expires_in] [datetime2](7) NULL,
    [refresh_token] [varchar](150) NULL,
    [issued_at] [datetime2](7) NULL,
    [user_id] [varchar](50) NOT NULL,
    [domain] [varchar](50) NULL,
    [scope] [varchar](150) NULL,
    CONSTRAINT [PK_OAuthUsers] PRIMARY KEY CLUSTERED
)

Store the access_token for facebook or openid. OpenID has a refresh token you can ask for, so store it as well

I have an ashx handler as my redirect_url. In that handler you can do all of the processing for each case, user already has an account in provider database, user does not have an account in provider database so we create one. All that neat crap :)

Have fun with it.

luviktor
  • 2,240
  • 2
  • 22
  • 23
CrazyCoderz
  • 1,351
  • 1
  • 15
  • 30
0

The ASP.NET MVC sample included with DotNetOpenId uses FormsAuthentication to log the user in after they have been authenticated by OpenID. It does not, as far as I can tell, do any integration with the Membership system.

Joel Mueller
  • 28,324
  • 9
  • 63
  • 88