OAuth with NancyFX and WorldDomination.Web.Authentication

posted on 31 Jan 2013 | NancyFX

One of the biggest pains of building websites, in my opinion, is implementing OAuth providers, it's often fiddly, doesn't work, and frameworks that are created to try make things easier, don't seem to make it easier.

So PureKrome and myself decided to create WorldDomination: Web Authentication

The idea behind this framework is to keep it super simple to implement OAuth into your website, without the bloat. The core framework ONLY deals with Google, Twitter, and Facebook authentication. It doesn't try to create a fancy UI for you, it doesn't require you to write lots and lots of code. You simply give it some info, it redirects, it comes back and gives you the authentication info.

Just recently the guys contributing to JabbR decided to use the library, and with feedback we added some really awesome support for NancyFX which I will show.

Installing

Installing the libary for Nancy requires installing the Nancy specific library.

PM> Install-Package Nancy.Authentication.WorldDomination

This will install:

  • Nancy.Authentication.WorldDomination
  • WorldDomination.Web.Authentication
  • RestSharp

The first package is the Nancy provider, this wires up all the routes and handles the redirect and callback.

The second package is the actual implementation, this has no dependency on NancyContext or System.Web

The last package is required by WorldDomination.Web.Authentication to process the callback and deserialize the response.

Configuring

Now that it's installed, we need to configure it, this is done one of two ways, by adding the information to the web.config, or by registering the information in the Bootstrapper

I'm going to show the web.config way, but you can visit the github wiki for WorldDomination.Web.Authentication on information to configure via the bootstrapper.

In the web.config add a config section like so

<section name="authenticationProviders"
         type="WorldDomination.Web.Authentication.Config.ProviderConfiguration, WorldDomination.Web.Authentication" />

Now add the authenticationProviders element.

<authenticationProviders>
  <providers>
    <add name="Facebook" key="470874...41" secret="02bb584...332fe2" />
    <add name="Google" key="58714009...ent.com" secret="npk...ooxCEY" />
    <add name="Twitter" key="Rb7qNNP...znFTbF6Q" secret="pP...7hu9c" />
  </providers>
</authenticationProviders>

Note: These are the key/secret you get when you register your application with the providers.

You can get the key/secret registering your apps:

  • Facebook: http://developers.facebook.com/docs/howtos/login/server-side-login/
  • Twitter: https://dev.twitter.com/
  • Google: https://code.google.com/apis/console/?pli=1#access

Note: Please refer to the 'Adding some buttons' section on the URLs for use when registering.

Implementing your callback

Now you need to implement a callback, this callback is what YOU want to do with the result from a successful (or failed) authentication, you need to implement this because we don't know what you have planned, if you want to create a session, set a cookie, use form authentication, what ever, that's up to you.

To do this you can create a new class and implement the interface IAuthenticationCallbackProvider

public class Test : IAuthenticationCallbackProvider
{
    public dynamic Process(NancyModule nancyModule, AuthenticateCallbackData model)
    {
        return nancyModule.Negotiate.WithView("AuthenticateCallback").WithModel(model);
    }
}

This example will simply respond with the view AuthenticateCallback and pass it the model with the data returned from the provider. Ideally you would check to see if the user is new, or if you need to add him to your database, or authenticate him with your system.

You can take a look at the implementation used by JabbR here, which I've mirrored as a gist here incase it is changed or moved and the link becomes dead.

If you're using Nancy with the default TinyIoC container, you don't need to register anything, it will automatically be picked up by Nancy.Authentication.WorldDomination and called.

Adding some buttons

Last of all, you need to add some buttons to the screen. This is where you have to link to some specific URLs.

Note: These links will be configurable in the future, but for now they are hard-coded.

The two URLs used by the system are:

  • Redirect: /authentication/redirect/provider key
  • Callback: /authentication/authenticatecallback?providerkey=provider key

Examples: The links you would add to your page would be similar to:

<a href="/authentication/redirect/Twitter"><img src="/Content/twitter_32.png" /></a>
<a href="/authentication/redirect/Facebook"><img src="/Content/facebook_32.png" /></a>
<a href="/authentication/redirect/Google"><img src="/Content/google_32.png" /></a>

These links are just normal hyperlinks, giving you absolute freedom and flexibility to style them any way you want. Because we have absolutely NO involvement in the generation of the links, we cannot get in the way.

All you need to do is ensure that the links provided to us look like the above.

Your callback urls would end up looking like:

  • /authentication/authenticatecallback?providerkey=twitter
  • /authentication/authenticatecallback?providerkey=facebook
  • /authentication/authenticatecallback?providerkey=google

Note: The urls are forced to be lowercase because Google is case sensitive, so when registering your app with google please make sure the url is registered all lowercase.

And you're done!

Now you can run your app:

We click on Google:

And we get redirected back to the website after allowing the authentication with Google:

That's all there is to it.

The sample can be found on github here:

You can find the source code on github:

And the Nuget packages

comments powered by Disqus