Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What mechanism do OmniAuth provide to ensure a secure login?

Using an omniauth login strategy a non-logged in user is redirected to an identity provider. The identity provider, will ensure a user is logged in then redirect the user to a callback url allowing the user to login to the third party site, using the identity provider's authentication.. This workflow is explained by Facebook in their chart here:

https://developers.facebook.com/docs/user_registration/flows/

How is it assured that a malicious user does not spoof this callback so that he can gain access to the authenticating user's third party account?

like image 356
Inc1982 Avatar asked Jul 15 '12 04:07

Inc1982


1 Answers

Like Facebook, Google implements the OAuth2.0 protocol for confirming identity. I'll take you through how the OAuth2.0 process is secure, how OmniAuth manages it and show you how to take a look under the hood to see it in action.

The OAuth2.0 process as managed by OmniAuth

The identity provider, will ensure a user is logged and then redirect the user to a callback url allowing the user to login to the third party site, using the identity provider's authentication.

Let me expand: The identity provider redirects the user to your application's callback URL that you supplied when you registered your application with that particular identity provider (ie Facebook, Google, etc). Since the user has been redirected, they send a request to your application containing an Authorization Code (supplied by your identity provider upon successful login).

How is it assured that a malicious user does not spoof this callback so that he can gain access to the authenticating user's third party account?

Here's where the magic happens. Our application takes this Authorization Code from the user, combines it with our Secret Code that we received upon registering our application and exchanges these with the identity provider for an almighty Access Code. Specifically, here are the steps taken to ensure this callback hasn't been spoofed:

  1. The entire process is managed through SSL (ie HTTPS). This makes intercepting any of these codes very difficult.
  2. Your identity provider validates the identity of the user by supplying the Authorization Code upon successful login and validating this code when received from your application.
  3. Your identity provider ensures the identity of your application by verifying your application's Secret Code.

Thus, it would be very difficult to intercept/decrypt a code and if you tried to spoof the redirect with a fake Authorization Code your login request would be rejected when your server tries to validate this code with your identification provider.

See it in action

OmniAuth manages most of this process behind the scenes. However, the following code should allow you to see it in action:

# Add the following gem to your Gemfile
gem 'httplog', group: :development

We'll make use of the httplog gem. This will essentially dump request logs into our log/development.log file. We need to initialize:

# Create a new file: config/initializers/httplog.rb
HttpLog.options[:logger] = Rails.logger if Rails.env.development?

Now launch a new Rails server for you application in the terminal:

bundle install
rails s

In a new tab, tail your development logs:

tail -f log/development.log

Go ahead and open a browser and login to your application with your chosen identity provider. Open the terminal window tailing your development logs and after the callback request from the user (Started GET "/auth/google_oauth2/callback?state=1) you should see something like:

[httplog] Connecting: accounts.google.com:443
[httplog] Sending: POST http://accounts.google.com:443/o/oauth2/token
[httplog] Data: client_id=123412341234-1234h1234h1234h1234h.apps.googleusercontent.com&client_secret=12341234123412341234&code=123412341234123412341234&grant_type=authorization_code&redirect_uri=https%3A%2F%2Fyourapp.domain.com%2Fauth%2Fgoogle_oauth2%2Fcallback
....
[httplog] Response:
{
  "access_token" : "123412341234123412341234",
  "token_type" : "Bearer",
  "expires_in" : 3599,
  ...
}

This is your server verifying the Authorization Code and verifying the Access Token. Next, OmniAuth uses this token to get some user information. Further down you should also see:

[httplog] Connecting: www.googleapis.com:443
[httplog] Sending: GET http://www.googleapis.com:443/plus/v1/people/me/openIdConnect
[httplog] Status: 200
[httplog] Response:
{
  "kind": "plus#personOpenIdConnect",
  "gender": "male",
  "sub": "1234123412341234",
  "name": "Matt",
  "given_name": "Matt",
  ...  
}

This represents OmniAuth fetching the information you requested using the Access Token.

A long explanation, but I hope it helps. Be sure to disable or remove the httplog gem before pushing to production!

like image 57
Matt Avatar answered Sep 28 '22 16:09

Matt