Blogs | Srijan

Using Ruby on Rails for Single Sign-On across multiple applications

Written by Naveen | Jun 29, 2016 7:00:00 AM

The way we develop our applications has changed significantly. To a great extent, we have adopted the service oriented design and generally have two or more applications communicating with each other. Now, if you have built-in authentication in your system, then you can either do a separate authentication for each application or have the single sign-on mechanism in place for all the applications.

Let’s see how we can implement the single sign-on for multiple applications. It is more about the concept rather than the code. Usually we are occupied with the thought of how to integrate our single sign-on or just look for the gems that can do the job for us. But once you get hold of the concept,  I bet you will be happy to integrate it yourself.

Let’s begin!

By and large, our design will look something like as shown in the image below. You can easily tweak this idea to suit your service oriented design:

 

In this picture we can see that we have an authentication mechanism before client visits the main applications (App1, App2, App3). The main problem with the session is - "How can a session be maintained across all the applications, whether you have these applications as sub domain or in totally different domains?"

So how do we ensure the authentication from a single application for all our services?

First, authenticate the user from the authenticating application in the same way as you would do your single application, say you use devise. Once it is done, now you have to decide how, and to which application, you wish to redirect the user. There will be one users table and all the applications will have access to it. In addition to that, we can have a random temporary authentication token generated in the application. This token is strored in the user table each time a user logs in, and destroyed that token when the user logs out from the application. I suggest logout or session destroy method in each of your applications to protect your session from being compromised. In case user does not logout from the application, then devise automatically logs out the user after some time. Watch out for that and put an observer in your app to clean the token.

class sessionController < ...
 def create
...
sign_in(user)
current_user.generate_temporary_authentication_token
...
end
def destroy
...
current_suer.clear_temporary_authentication_token
sign_out(current_user)
...
end
end

In user model

class User
 def generate_temporary_authentication_token
self.temporary_authentication_token = Devise.friendly_token
self.save
end

def clear_temporary_authentication_token
self.temporary_authentication_token = nil
self.save
end
end

From your authentication application you redirect the user to one of the main applications;

Class WelcomeController < ...
def redirect_user
return redirect_to app_path, :token => current_user.temporary_authentication_token
end
end

Now in any of your main applications you can have something like this

class HomeController < ...
def index
token = params[:token]
user = User.where(
:temporary_authentication_token => token
).first
 return redirect_to authentication_app if user.blank? || token.blank?
sign_in(user)
end
end

This code would be duplicated across the main applications. This is just a simple concept on how you can approach this single sign-on problem. You can figure out the areas where you need to put the kind of security and protect session hi-jacking. It’s mainly about maintaining the session in each of your applications.

The same concept can be applied on other platforms as well.

To me, it seems quite interesting to have a single authentication mechanism, and I welcome all the readers to provide their input on how it can be improved or implemented.