forked from oauth-xx/oauth2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
142 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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 | ||
|