Every day we build web and mobile applications to cover needs of our users and make their life better. But ask yourself: what might happen if you have several application under the same brand? For sure multiple applications will have a few pros and cons relative to single application. These differences will include technical, app maintenance cost, design, learning curve, user experience, DevOps, marketing, SEO and other parts. Every department in your company will see different parts as the most vital for the applications. But who is right and where should you put main efforts?

To solve that question we have to think about the application aim. Most of them are designed to help people do some specific things like time tracking, route planning, material calculation and etc. That’s why users will only notice an issue if their problem is not solved properly with minimal efforts from their side. As a result user does not care what way do you provide your problem-solver service until it works fine and does not require extra actions from the user.

I see a huge amount of user experience topics to discuss here but let’s go step by step and start with one of the first actions a user performs. Yes, I mean sign in action. It is easy to do in a single application but requires some work if you have multiple apps and want to provide a single sign on feature.

 

Central Authentication Service (CAS)

 

If you are not sure what I am talking about – take a look at google applications and the way you perform sign in. It does not matter where you press sign in button – you are being redirected to central authentication service (CAS) and on successful sign on – you are redirected back. To make sure we are going in the right direction we have to state main CAS features which will make users’ and developers’ lives better:

 

  • Provide credentials once and permit access to multiple applications
  • Independent of applications programming languages
  • Extendable authentication algorithms

 

If you drop any of the points above I bet you will have big troubles in the future. Think carefully about these vital points before you start – you might have extra for your case. Since we understand our aim – we can go into implementation details.

 

Choose right solution

 

Once you start searching for existing CAS solutions in Ruby world you encounter two similar sources:

 

 

And the bad fact is that at first glance it seems like RubyCAS is much more popular. In fact it WAS a popular solution but died some time ago. Right now it tries to get back to alive state but the process is very slow. Thus I recommend using rbCAS for single sign on solution. First of all it provides an awesome guide and a template CAS application to let you start rapidly.

 

SSO with rbCAS

 

First of all I recommend you to read documentation very carefully and understand how SSO and CAS protocol works. Visual explanations of any complex interactions usually helps me and I hope will help you as well.

cas architecture

 

 

As you see the architecture assumes presence of a single CAS server and multiple CAS clients, which use different protocols and written in different languages. More than that authentication sources are also configurable and may be extended.

 

CAS server

 

We do not have to reinvent a wheel here and can start with template CAS server. This will save you a lot of time.

All you have to do is open your terminal and run:

 

  1. git clone [email protected]:rbCAS/CASinoApp.git
  2. bundle install
  3. cp config/database.yml.example.<database> config/database.yml
  4. cp config/cas.yml.example config/cas.yml
  5. rake db:create db:migrate
  6. rails s –p 3003

 

Your CAS server is ready! In six commands you got your own CAS server with awesome frontend. Here are screenshots of login and sessions pages.

login

session-overview

 

 

 

ActiveRecord Authenticator

 

Template app does not perform any authentication except static authentication. That is good for test cases but not for real applications. Most real applications allow you to sign up with email/username and password. To make sure your CAS server knows how to handle that you should apply next changes:

 

Gemfile

[ruby]
gem ‘casino-activerecord_authenticator’
[/ruby]

 

config/cas.yml

[ruby]
authenticators:
auth_user_by_email:
authenticator: “ActiveRecord”
options:
connection:
adapter: “postgresql”
host: “localhost”
username: “postgres”
password: “postgres”
database: “casino_app”
table: “users”
username_column: “email”
password_column: “encrypted_password”
extra_attributes:
email: “email”
username: “username”
uuid: “uuid”

auth_user_by_username:
authenticator: “ActiveRecord”
options:
connection:
adapter: “postgresql”
host: “localhost”
username: “postgres”
password: “postgres”
database: “casino_app”
table: “users”
username_column: “username”
password_column: “encrypted_password”
extra_attributes:
email: “email”
username: “username”
uuid: “uuid”

[/ruby]

 

You could notice that we have two very similar authenticators. In fact ActiveRecord authenticator allows us to authenticate a user by two columns and we have two scenarios here: username-password, email-password. That’s why we user “email” as a username_column if the first authenticator hash and “username” in the second one.

 

OAuth authenticator

 

The best way to add Facebook and Twitter authenticators to your CAS server is to use devise and devise_cas_authenticatable gems. They will integrate OAuth authentication support seamlessly. Here are the changes you have to apply:

 

Gemfile

[ruby]
gem ‘devise’
gem ‘devise_cas_authenticatable’

gem ‘omniauth-facebook’
gem ‘omniauth-twitter’
[/ruby]

 

config/initializers/devise.rb

[ruby]
config.omniauth :facebook, Rails.application.secrets.facebook_app_id, Rails.application.secrets.facebook_app_secret
config.omniauth :twitter, Rails.application.secrets.twitter_app_key, Rails.application.secrets.twitter_app_secret[/ruby]

 

app/models/user.rb

[ruby]
devise …, :cas_authenticatable, :omniauthable, :omniauth_providers => [:facebook, :twitter]
[/ruby]

 

app/views/casino/sessions/new.html.erb

[ruby]
<%= link_to “Sign in with Facebook”, omniauth_authorize_path(:user, :facebook) %>
<%= link_to “Sign in with Twitter”, omniauth_authorize_path(:user, :twitter) %>
[/ruby]

 

OAuth authentication is ready to use! Also I want to mention that creating a custom authenticator is not a problem here. You can use gem casino-activerecord_authenticator as a good example and substitute your code in the right places. I will not cover that case in the article but keep in mind that it is easy to do.

 

Summary

 

Multiple applications development and support contains a huge amount of non-trivial questions, which I will touch in the next articles. Here I explained how single sign on simplifies user’s workflow and what is the best way to implement it. Your next step is to try it and make your applications more user friendly. Good luck!

Questions? Comments? Let’s talk about them in the comments section below.

 

How useful was this post?

Click on a star to rate it!

Average rating 4.7 / 5. Vote count: 41

No votes so far! Be the first to rate this post.

We are sorry that this post was not useful for you!

Let us improve this post!

Tell us how we can improve this post?


Author

VP of Business Development at Rubyroid Labs

3 Comments

  1. Love that you spent time sharing your discoveries. So your blog is targeting mostly developers?

    • Alex Galesnik Reply

      Thanks. We build a community where software engineers, architectures, CTOs and business owners come to get some ideas. They are our target audience.

  2. your article is good thank you for sharing about CAS. but i got an error when trying to rake db create. it say
    rake aborted!
    LoadError: cannot load such file — bundler/setup
    /home/shagnaz/Desktop/caas/CASinoApp/config/boot.rb:6:in `’
    /home/shagnaz/Desktop/caas/CASinoApp/config/application.rb:1:in `’
    /home/shagnaz/Desktop/caas/CASinoApp/Rakefile:5:in `’
    /home/shagnaz/.rvm/gems/ruby-2.2.3@casinoapp/gems/rake-12.3.1/exe/rake:27:in `’
    /home/shagnaz/.rvm/gems/ruby-2.2.3@casinoapp/bin/ruby_executable_hooks:15:in `eval’
    /home/shagnaz/.rvm/gems/ruby-2.2.3@casinoapp/bin/ruby_executable_hooks:15:in `’
    (See full trace by running task with –trace)

Write A Comment