Company wide Single Sign On(SSO) using Devise custom authentication strategy

It is a common requirement to have a single sign on for multiple software services provided by a company, something like google account with multiple google services like gmail,docs,google+ . In order to do this it would be best to have a RESTful application responsible for authentication and have all other services authenticate against this application.

To authenticate users of our rails application against an external API we add a custom authentication strategy to devise. Devise is a flexible authentication solution for Rails based on Warden. Warden uses the concept of cascading strategies to determine if a request should be authenticated. Warden will try strategies one after another until either, – One succeeds – No Strategies are found relevant – A strategy Fails.

These are the steps to add custom authentication strategy.

1. Create your own strategy implementation inheriting from Devise::Strategies::Base



      classFromSession < ::Devise::Strategies::Base
          # this strategy is only valid if there is a url_token
          # in the params hash.
          # e.g. http://myapp?url_token=mysecrettoken
          # lookup session data with external api
          session_data = get_session_data_from_api(params[:url_token])
          # check if token was valid and authorise if so
            # session lookup failed so fail authentication with message from api 
            # we got some valid user data
2. Add this strategy to warden
config.warden do|manager|

  manager.strategies.add(:custom_auth, CustomAuth::Devise::Strategies::FromSession)
  manager.default_strategies(:scope=> :user).unshift :custom_auth
Devise flow diagram
  1. The HTTP request enters the rack stack.
  2. Warden gets the request and forwards it in the rack stack, adding an environment variable “warden” that points to an authentication proxy.
  3. The request gets dispatched to the rails controller, which may call authenticate_user! from a filter. This is an alias for request.env[‘warden’].authenticate!(:scope => :user).
  4. The warden proxy picks an authentication strategy. Any strategy for which valid? returns true is tried.
  5. When authentication succeeds, a user object is returned to the controller. When it fails, the symbol :warden is thrown down the stack, and caught by the warden rack application. The latter will return a response, which is a redirect to the login page by default. This can be overridden by calling warden.custom_response!.
Testing custom authentication strategy
To test the custom authentication strategy use Fakeweb and get a list of responses from the external API an add different test cases.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s