Skip to content

Commit

Permalink
Add raw_info to auth_hash for response_type id_token
Browse files Browse the repository at this point in the history
* The complete id_token is now a part of the hash that is returned to the application
* Bugfix: Redefining env method for Strategy class caused race condition in test execution
  • Loading branch information
Espen Wilhelmsen committed Sep 16, 2019
1 parent 67665b1 commit 738354f
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 6 deletions.
14 changes: 9 additions & 5 deletions lib/omniauth/strategies/openid_connect.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,6 @@ def callback_phase
invalid_state = params['state'].to_s.empty? || params['state'] != stored_state

raise CallbackError.new(params['error'], error_description, params['error_uri']) if error

raise CallbackError, 'Invalid state parameter' if invalid_state

return unless valid_response_type?
Expand All @@ -126,7 +125,7 @@ def callback_phase
discover!
client.redirect_uri = redirect_uri

return id_token_callback_phase if options.response_type.to_s == 'id_token'
return id_token_callback_phase if configured_response_type == 'id_token'

client.authorization_code = authorization_code
access_token
Expand Down Expand Up @@ -307,20 +306,25 @@ def id_token_callback_phase
env['omniauth.auth'] = AuthHash.new(
provider: name,
uid: user_data['sub'],
info: { name: user_data['name'], email: user_data['email'] }
info: { name: user_data['name'], email: user_data['email'] },
extra: { raw_info: user_data }
)
call_app!
end

def valid_response_type?
return true if params.key?(options.response_type)
return true if params.key?(configured_response_type)

error_attrs = RESPONSE_TYPE_EXCEPTIONS[options.response_type.to_s]
error_attrs = RESPONSE_TYPE_EXCEPTIONS[configured_response_type]
fail!(error_attrs[:key], error_attrs[:exception_class].new(params['error']))

false
end

def configured_response_type
@configured_response_type ||= options.response_type.to_s
end

class CallbackError < StandardError
attr_accessor :error, :error_reason, :error_uri

Expand Down
40 changes: 39 additions & 1 deletion test/lib/omniauth/strategies/openid_connect_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ def test_callback_phase(session = {}, params = {})
strategy.options.issuer = 'example.com'
strategy.options.client_signing_alg = :RS256
strategy.options.client_jwk_signing_key = File.read('test/fixtures/jwks.json')
strategy.options.response_type = :code

id_token = stub('OpenIDConnect::ResponseObject::IdToken')
id_token.stubs(:verify!).with(issuer: strategy.options.issuer, client_id: @identifier, nonce: nonce).returns(true)
Expand Down Expand Up @@ -453,7 +454,8 @@ def test_state

def test_dynamic_state
# Stub request parameters
Strategy.send(:define_method, 'env', -> { { QUERY_STRING: { state: 'abc', client_id: '123' } } })
request.stubs(:path_info).returns('')
strategy.call!('rack.session' => { }, QUERY_STRING: { state: 'abc', client_id: '123' } )

strategy.options.state = lambda { |env|
# Get params from request, e.g. CGI.parse(env['QUERY_STRING'])
Expand Down Expand Up @@ -529,6 +531,42 @@ def test_public_key_with_hmac
strategy.options.client_signing_alg = :HS256
assert_equal strategy.options.client_options.secret, strategy.public_key
end

def test_id_token_auth_hash
state = SecureRandom.hex(16)
nonce = SecureRandom.hex(16)
strategy.options.response_type = 'id_token'
strategy.options.issuer = 'example.com'

id_token = stub('OpenIDConnect::ResponseObject::IdToken')
id_token.stubs(:verify!).returns(true)
id_token.stubs(:raw_attributes, :to_h).returns(
{
"iss": "http://server.example.com",
"sub": "248289761001",
"aud": "s6BhdRkqt3",
"nonce": "n-0S6_WzA2Mj",
"exp": 1311281970,
"iat": 1311280970,
}
)

request.stubs(:params).returns('state' => state, 'nounce' => nonce, 'id_token' => id_token)
request.stubs(:path_info).returns('')

strategy.stubs(:decode_id_token).returns(id_token)
strategy.stubs(:stored_state).returns(state)

strategy.call!('rack.session' => { 'omniauth.state' => state, 'omniauth.nonce' => nonce })
strategy.callback_phase

auth_hash = strategy.send(:env)['omniauth.auth']
assert auth_hash.key?('provider')
assert auth_hash.key?('uid')
assert auth_hash.key?('info')
assert auth_hash.key?('extra')
assert auth_hash['extra'].key?('raw_info')
end
end
end
end

0 comments on commit 738354f

Please sign in to comment.