Saturday, November 8, 2014

In this blog post, I discuss a few implementations of authentication for web applications, particularly one that involves python language. There are several available for NodeJs and many companies already use them for the application and often they rely on OAuth and SSO. I haven't seen the use of CAS in companies but I have seen it in educational institutions. Today I want to quickly review some of the design behind the registration packages for django. There are quite a few available namely:
django - social auth - which makes social authentication simpler.
Pinax - which makes it popular for websites
django-allauth which integrates authentication, addressing, registration, account management as well as 3rd party social account
django-userena which makes user accounts simpler
django-social registration which combines OpenID, OAuth and FacebookConnect
django-registration which is probably the most widely used for the framework
django-email-registration which claims to be very simple to use and other such packages.
These implementations are essentially to facilitate the user account registration via templated views and a database or other membership provider backends.

There are other implementations as well such as EngineAuth, SimpleAuth and AppEngine-OAuth-Library. EngineAuth does the multiprovider authentication and saves the userid to a cookie.
SimpleAuth supports OAuth and OpenID. AppEngine-OAuth now provides user authentication against third party websites.


 However, one of the things I'm looking for is a NodeJs style implementation that uses the providers as strategy. If we look at the passport implementation for example, I like the fact that we can easily change the strategy to direct against the provider of choice. In fact the interface is something that makes it quite clear.
You use methods like
app.get('/login', function(req, res, next)) {
passport.authenticate('AuthBackendOfChoice', function (req,res, next) {
:
etc.
You also use methods like the following:
var passport = require('passport') , OAuthStrategy = require('passport-oauth').OAuthStrategy; passport.use('provider', new OAuthStrategy({ requestTokenURL: 'https://www.provider.com/oauth/request_token', accessTokenURL: 'https://www.provider.com/oauth/access_token', userAuthorizationURL: 'https://www.provider.com/oauth/authorize', consumerKey: '123-456-789', consumerSecret: 'shhh-its-a-secret' callbackURL: 'https://www.example.com/auth/provider/callback' }, function(token, tokenSecret, profile, done) { User.findOrCreate(..., function(err, user) { done(err, user); }); } ));
I haven't found a django-passport implementation in the repo or for that matter any python-passport implementation.
but Netor technologies has a mention for something that's same name but is also an interesting read.
For example, they create a table to keep the application_info and user_info. The application_info is similar to the client in the OAuth protocol. In that it keeps track of the applications as well as the user information. The user information is keeping track of usernames and passwords. The user_applications is the mapping between the user and the applications.
The authentication is handled using a Challenge Response scheme.  The server responds with the user's password salt along with a newly generated challenge salt and a challenge id. The client sends back a response with the hash resulting from hash(hash(password+salt) + challenge). These are read by the server and deleted after use. There's no need to keep them.
The code for create user looks like this:
def create(store, user, application = None):
      if application is None:
          application = Application.findByName(unicode('passport'))
      result = UserLogin.findExisting(user.userid, application.applicationid)
      if result is None:
              result = store.add(UserLogin(user, application))
              store.commit()
      return result
and the authentication methods are handled in the controllers. The BaseController has the method  to get user login and the servicecontroller has the method to authenticate via a challenge.
This seems a clean example for doing a basic registration of user accounts and integrating with the application.
However, I'm wondering why we don't have the passport library ported to python yet.
The implementation for that is also relatively easy.
One we have to define the class for Strategy and Passport. Next we implement the authenticate method and target the appropriate strategy. An out of box SessionStrategy may also be provided. If we look at the authenticate method, we are issuing a challenge and attempting to validate against one of the Strategies until there is none left. In fact, the passport framework implements just the initialize and the authenticate method.
I've listed EngineAuth, SimpleAuth and AppEngine-OAuth but they are still not the same to implement. 

No comments:

Post a Comment