9

Building a website that also will require an API and therefore (possibly) OAuth support for login I'm in doubt how to approach he user and authentication-part.

So I've got an ASP.NET MC4 application with RavenDB.

What is the best approach?

  • To use one of the Membership providers for RavenDB and deal with the Oauth separately in the API part? Ex. Griffin's solution here.

  • Or to make a custom solution that kind of re-implements the membership-crap and supports OAuth.

I'm not really sure where to start, any suggestions on how to do this is appreciated.

esbenr
  • 1,356
  • 1
  • 11
  • 34

2 Answers2

10

enter image description here

** Clicky-click for da GitHub project **

IMO, forget storing usernames and passwords. That's crazy talk! Let people login with their Facebook, Google or Twitter credentials. That's the 80%'s for the common websites.

Authentication and storing the credentials are two different tasks IMO. For example, I don't care where you authenticate against .. and once you do .. I don't care how you store that data :)

Personally, I would store it in a RavenDb .. but that's my personal choice.

As such -> keeping these two tasks SEPARATE is (IMO) crucial.

enter image description here

So lets look at some codez ....

public ActionResult AuthenticateCallback(string providerKey)
{
    // SNIP SNIP SNIP SNIP

    var model = new AuthenticateCallbackViewModel();
    try
    {
        // SNIP SNIP SNIP SNIP

        // Complete the authentication process by retrieving the UserInformation from the provider.
        model.AuthenticatedClient = _authenticationService.CheckCallback(providerKey, Request.Params, state.ToString());


        // Create a new user account or update an existing account.
        // Whatever you end up doing, this is the part u want to
        // pass this data to your repository (eg. RavenDb, Sql Server, etc)
        // I'll use RavenDb in this example...
        // And yes .. this is a contrite example. U might want to check for
        // existing email or id or whatever u need to do, etc.
        var myUser = Mapper.Map(model.AuthenticatedClient);
        session.Store(myUser);
        session.SaveChanges();

        // SNIP SNIP SNIP SNIP
    }
    catch (Exception exception)
    {
        model.Exception = exception;
    }

    return View(model);
}

So lets look at what I've done. I've snipped out any verbose stuff (value checks, etc) which are just noise in this SO answer.

First, I handle the Authenticate callback. Eg. I've just gone to Facebook and it's said 'yes! you ARE you' .. and it's coming back to my website, with some data i've asked it to give me.

Next... we are given some data from Facebook .. but this might not be in the format we want to put it into, in RavenDb. So i convert it from the old format to a new shiney User class which is what you'll stick in your Db.

Third - I store this in the Db. This is where you would do any custom DB logic

that's it.

M O D U L A R I Z E T H A T S H I T

The.End.

Now excuse me .. there's a few hours left before The Apocalypse. I must prepare myself.

Pure.Krome
  • 84,693
  • 113
  • 396
  • 647
  • I did exactly this. My need is to identify the user, not to authenticate - they can do that against whatever. So this works. Now that I have stored the User in my DB, I need to use it together with the ASP.NET membership system. So i can flag actions with [Authorize] and [AllowAnonymous], return url etc. built-in features in ASP.NET. How do I do that? With this: http://www.codethinked.com/setting-up-authentication-in-aspnet-mvc – esbenr Dec 29 '12 at 14:40
  • 2
    @esbenr To use the `[Authorize]`, etc attributes .. you **DO NOT** (and I repeat, **DO NOT**) need to use ASP.NET Membership system. **PLEASE DO NOT USE THAT AT ALL, UNDER ANY CIRCUMSTANCES** (Google for the 1000000 reasons why). To leverage `[Authorize]`, etc .. u just need to use store the use info in an `IPrincipal` and `IIdentity` (yes, 2x I's). Just create a new `GenericPrincipal` and in that, add a new `GenericIdentity`. Google for those for more code :) – Pure.Krome Dec 29 '12 at 14:54
  • Thanks, thats what I ended up doing. I only used the Auth ticket + cookie to get the static USER principal to work - it works like a charm :-) This method is stated lot of places on the internet-thingie. BTW: I created a custom IPrinciple implementation AND a custom IIdentity impl. thus i wanted more properties on my User context. Thanks for your reply. /esbenr – esbenr Jan 10 '13 at 07:32
  • i've also got another package that has the principal and identity stuff in it. In fact, it's for .NET 4.5 and uses CLAIMS (which is the new sexy hip and kewl shit all the kewl kids are now using). Where is it? => https://github.com/PureKrome/WorldDomination.Security . Check out the sample in there, about how to use it. It's on nuget of course :) – Pure.Krome Jan 10 '13 at 10:32
  • Hey @Pure.Krome liking very much your solution. Would you be able to update the link (https://github.com/PureKrome/WorldDomination.Web.Authentication/blob/master/Code/WorldDomination.Web.Authentication.Test/WorldDomination.Web.Authentication.Test.Mvc.Advanced/Controllers/HomeController.cs#L59) it is returning a 404 for me? – Mr. Mr. Apr 10 '13 at 21:06
0

Well. The membership providers are bloated. If you don't plan on using the features in them but just OAuth I would not use them. The SimpleMembership and the oath provider supplied in MVC4 is unfortunately even a larger mess.

So your options are:

  1. Use the SimpleMembership
  2. The built in OAuth support
  3. Use a custom membership provider
  4. Use a custom oauth provider

If you plan to stick to #3 I would recommend using mine (in Griffin.MvcContrib). It's not trivial to build a membership provider.

As for oauth you have a solution like: https://github.com/rafek/SimpleSocialAuth

jgauffin
  • 99,844
  • 45
  • 235
  • 372