/oauth2-example

Example / Doc of howto use oauth2 as a service and as a provider

Primary LanguageRuby

oauth2-example

This repo includes the demo use of oauth2 in rails, for both provider and client app.

1. Background

1.1 The OAuth 2.0 protocol

As described in the spec:

OAuth provides a method for clients to access a protected resource on behalf of a resource owner. Before a client can access a protected resource, it must first obtain authorization from the resource owner, then exchange the access grant for an access token (representing the grant’s scope, duration, and other attributes). The client accesses the protected resource by presenting the access token to the resource server.

The most recent version is v0.10 , and most of the gems/plugins available is based on the v0.9 version of the spec.

And a abstract protocol flow is illustrated here: http://tools.ietf.org/html/draft-ietf-oauth-v2-09#section-1.3

1.2 Gems/Plugins availabe

Because the oauth2 protocol is pretty new itself, the gems/plugins are under development, and some of them are in alpha state and then not maintained anymore.

Below is a list of gems/plugins implemented oauth2.

provider:

oauth2_provider: https://github.com/ThoughtWorksStudios/oauth2_provider
oauth2-ruby: https://github.com/aflatter/oauth2-ruby
rack-oauth2-server: https://github.com/flowtown/rack-oauth2-server

client:

OAuth2 https://github.com/intridea/oauth2
devise_oauth2_facebook https://github.com/mooktakim/devise_oauth2_facebook
authlogic_oauth2 https://github.com/andyhite/authlogic_oauth2

considering the stability and activity, we choose the “oauth2_provider” plugin for provider app and “oauth2” for client app.

Note: both plugins and gems are modified to compatible with the spec and work with each other.

2. Setting up sample apps

There are 2 sample apps in the repo.

2.1 Blog, the provider app

The blog app is a provider app, it provide the oauth2 authentication, you can register a client app and authenticate against it.
It also provide a UI to checkout registered clients.

here are the steps for setting up the provider app

  1. rake db:create
  2. rake db:seed
  3. start the application with ./script/server
  4. login with blogger/123456 create several articles
  5. click the “Clients” link on the top right
  6. create a client app and name it “publisher”, with Redirect uri: “http://localhost:4000/oauth/callback”
  7. when done, copy the Client id and Client secret for later use.

2.2 Publisher, the client app

The publisher app is a client app, you can config the oauth2 authentication information there, and get protected resources from the provider

here are the steps for setting up the client app:

  1. go to the app/controllers/oauth_controller.rb, and replace the client_id and client_secret with the pair you got in setting up provider app
  2. rake db:create
  3. rake db:seed
  4. start server with ./script/server -p 4000
  5. click the “get articles!” link and login with publisher/123456
  6. when redirected to Blog app and asked for login, login with blogger/123456 on the Blog app
  7. make sure check the checkbox and click submit when ask for permission.
  8. then you should see the articles returned from the provider app

3. Setting up for new project

normally you just set up new project as described in the above section, just remember use the gem/plugin nested in the sample app.
below is the explanation of what have been changed in the gem/plugin and why.

3.1 Provider setting up

You can follow the provider setting up instructino here: https://github.com/ThoughtWorksStudios/oauth2_provider

and remember use the plugin nested in the sample provider app, if not you may get the following exception

ArgumentError in Oauth2::provider::oauthauthorizeController#index
A copy of ApplicationController has been removed from the module tree but is still active!

3.2 Client setting up


def access_token_url(params = {})
  path = options[:access_token_url] || options[:access_token_path] || "/oauth/access_token"
  # according to http://tools.ietf.org/html/draft-ietf-oauth-v2-09#section-4.1.1
  # :grant_type is required and should be set to authorization-code
  params.merge!({:grant_type => "authorization-code"})
  
  connection.build_url(path, params).to_s
end

def authorize_url(params = { :response_type => 'code' })
  path = options[:authorize_url] || options[:authorize_path] || "/oauth/authorize"
  # according to http://tools.ietf.org/html/draft-ietf-oauth-v2-09#section-3
  # response_type is required
  params.merge!({:response_type => 'code'})
  connection.build_url(path, params).to_s
end