Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

add assertion strategy #105

Merged
merged 1 commit into from

2 participants

@dorren

No description provided.

lib/oauth2/version.rb
@@ -1,3 +1,3 @@
module OAuth2
- VERSION = "0.7.1"
+ VERSION = "0.7.1.1"
@sferik Collaborator
sferik added a note

We'll handle the versioning. Can you please remove this from your commit?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
oauth2.gemspec
@@ -6,6 +6,7 @@ Gem::Specification.new do |gem|
gem.add_dependency 'httpauth', '~> 0.1'
gem.add_dependency 'multi_json', '~> 1.0'
gem.add_dependency 'rack', '~> 1.4'
+ gem.add_dependency 'jwt', '~>0.1.4'
@sferik Collaborator
sferik added a note

This is very minor but could you please add a space after the ~> for formatting consistency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
@sferik
Collaborator

Other than the two minor issues I mentioned inline, this commit looks good to me. Can you please make those minor changes and squash them into a single commit or just commit them with git commit --amend and then force push to your remote branch (git push -f origin assertion)?

@dorren

I've made those 2 changes.

@sferik sferik merged commit bddbdc6 into intridea:master
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 12, 2012
  1. @dorren

    add assertion strategy

    dorren authored
This page is out of date. Refresh to see the latest.
View
6 README.md
@@ -61,9 +61,9 @@ instance will be returned as usual and on 400+ status code responses, the
Response instance will contain the OAuth2::Error instance.
## Authorization Grants
-Currently the Authorization Code, Resource Owner Password Credentials, and Client Credentials
+Currently the Authorization Code, Resource Owner Password Credentials, Client Credentials, and Assertion
authentication grant types have helper strategy classes that simplify client
-use. They are available via the #auth_code, #password, and #client_credentials methods respectively.
+use. They are available via the #auth_code, #password, #client_credentials, and #assertion methods respectively.
auth_url = client.auth_code.authorize_url(:redirect_uri => 'http://localhost:8080/oauth/callback')
token = client.auth_code.get_token('code_value', :redirect_uri => 'http://localhost:8080/oauth/callback')
@@ -72,6 +72,8 @@ use. They are available via the #auth_code, #password, and #client_credentials
token = client.client_credentials.get_token
+ token = client.assertion.get_token(assertion_params)
+
If you want to specify additional headers to be sent out with the
request, add a 'headers' hash under 'params':
View
1  lib/oauth2.rb
@@ -4,5 +4,6 @@
require 'oauth2/strategy/auth_code'
require 'oauth2/strategy/password'
require 'oauth2/strategy/client_credentials'
+require 'oauth2/strategy/assertion'
require 'oauth2/access_token'
require 'oauth2/response'
View
4 lib/oauth2/client.rb
@@ -153,5 +153,9 @@ def password
def client_credentials
@client_credentials ||= OAuth2::Strategy::ClientCredentials.new(self)
end
+
+ def assertion
+ @assertion ||= OAuth2::Strategy::Assertion.new(self)
+ end
end
end
View
75 lib/oauth2/strategy/assertion.rb
@@ -0,0 +1,75 @@
+require 'httpauth'
+require 'jwt'
+
+module OAuth2
+ module Strategy
+ # The Client Assertion Strategy
+ #
+ # @see http://tools.ietf.org/html/draft-ietf-oauth-v2-10#section-4.1.3
+ #
+ # Sample usage:
+ # client = OAuth2::Client.new(client_id, client_secret,
+ # :site => 'http://localhost:8080')
+ #
+ # params = {:hmac_secret => "some secret",
+ # # or :private_key => "private key string",
+ # :iss => "http://localhost:3001",
+ # :prn => "me@here.com",
+ # :exp => Time.now.utc.to_i + 3600}
+ #
+ # access = client.assertion.get_token(params)
+ # access.token # actual access_token string
+ # access.get("/api/stuff") # making api calls with access token in header
+ #
+ class Assertion < Base
+ # Not used for this strategy
+ #
+ # @raise [NotImplementedError]
+ def authorize_url
+ raise NotImplementedError, "The authorization endpoint is not used in this strategy"
+ end
+
+ # Retrieve an access token given the specified client.
+ #
+ # @param [Hash] params assertion params
+ # pass either :hmac_secret or :private_key, but not both.
+ #
+ # params :hmac_secret, secret string.
+ # params :private_key, private key string.
+ #
+ # params :iss, issuer
+ # params :aud, audience, optional
+ # params :prn, principal, current user
+ # params :exp, expired at, in seconds, like Time.now.utc.to_i + 3600
+ #
+ # @param [Hash] opts options
+ def get_token(params={}, opts={})
+ hash = build_request(params)
+ @client.get_token(hash, opts.merge('refresh_token' => nil))
+ end
+
+ def build_request(params)
+ assertion = build_assertion(params)
+ {:grant_type => "assertion",
+ :assertion_type => "urn:ietf:params:oauth:grant-type:jwt-bearer",
+ :assertion => assertion,
+ :scope => params[:scope]
+ }.merge(client_params)
+ end
+
+ def build_assertion(params)
+ claims = {:iss => params[:iss],
+ :aud => params[:aud],
+ :prn => params[:prn],
+ :exp => params[:exp]
+ }
+ if params[:hmac_secret]
+ jwt_assertion = JWT.encode(claims, params[:hmac_secret], "HS256")
+ elsif params[:private_key]
+ jwt_assertion = JWT.encode(claims, params[:private_key], "RS256")
+ end
+ end
+ end
+ end
+end
+
View
1  oauth2.gemspec
@@ -6,6 +6,7 @@ Gem::Specification.new do |gem|
gem.add_dependency 'httpauth', '~> 0.1'
gem.add_dependency 'multi_json', '~> 1.0'
gem.add_dependency 'rack', '~> 1.4'
+ gem.add_dependency 'jwt', '~> 0.1.4'
gem.add_development_dependency 'addressable'
gem.add_development_dependency 'multi_xml'
gem.add_development_dependency 'rake'
View
57 spec/oauth2/strategy/assertion_spec.rb
@@ -0,0 +1,57 @@
+require 'helper'
+
+describe OAuth2::Strategy::Assertion do
+ let(:client) do
+ cli = OAuth2::Client.new('abc', 'def', :site => 'http://api.example.com')
+ cli.connection.build do |b|
+ b.adapter :test do |stub|
+ stub.post('/oauth/token') do |env|
+ case @mode
+ when "formencoded"
+ [200, {'Content-Type' => 'application/x-www-form-urlencoded'}, 'expires_in=600&access_token=salmon&refresh_token=trout']
+ when "json"
+ [200, {'Content-Type' => 'application/json'}, '{"expires_in":600,"access_token":"salmon","refresh_token":"trout"}']
+ end
+ end
+ end
+ end
+ cli
+ end
+
+ let(:params) { {:hmac_secret => 'foo'}}
+
+ subject {client.assertion}
+
+ describe "#authorize_url" do
+ it "should raise NotImplementedError" do
+ lambda {subject.authorize_url}.should raise_error(NotImplementedError)
+ end
+ end
+
+ %w(json formencoded).each do |mode|
+ describe "#get_token (#{mode})" do
+ before do
+ @mode = mode
+ @access = subject.get_token(params)
+ end
+
+ it 'returns AccessToken with same Client' do
+ @access.client.should == client
+ end
+
+ it 'returns AccessToken with #token' do
+ @access.token.should == 'salmon'
+ end
+
+ it 'returns AccessToken with #expires_in' do
+ @access.expires_in.should == 600
+ end
+
+ it 'returns AccessToken with #expires_at' do
+ @access.expires_at.should_not be_nil
+ end
+ end
+ end
+
+end
+
Something went wrong with that request. Please try again.