Skip to content

Commit

Permalink
Add audience to the client_options (#179)
Browse files Browse the repository at this point in the history
* Add `audience` to the `client_options`

I've come across an issue where the `identifier` wasn't equal to the `audience` in the token.
This resulted in verification errors because currently it will verify the `aud` against the `identifier` if no `audience` is specified.

In this PR, I introduced the `audience` as `client_options` and will pass this along in the `verify!` of the `decoded_id_token` so the openid_connect gem [can handle the expected audience](https://github.com/nov/openid_connect/blob/e1eb8ea962af43752b1aed2c1063a3e24f96c5bc/lib/openid_connect/response_object/id_token.rb#L30-L32)

* Only pass along `audience` if it is specified

* Update README.md

Co-authored-by: Roger Meier <r.meier@siemens.com>

---------

Co-authored-by: Roger Meier <r.meier@siemens.com>
  • Loading branch information
manuelvanrijn and bufferoverflow authored Jul 5, 2024
1 parent 9b2a67d commit 23d4b13
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 3 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ These are the configuration options for the client_options hash of the configura
| scheme | The http scheme to use | https | |
| host | The host of the authorization server | nil | |
| port | The port for the authorization server | 443 | |
| audience | The intended consumer (`aud` field) of the id_token | nil | |
| authorization_endpoint | The authorize endpoint on the authorization server | /authorize | yes |
| token_endpoint | The token endpoint on the authorization server | /token | yes |
| userinfo_endpoint | The user info endpoint on the authorization server | /userinfo | yes |
Expand Down
12 changes: 9 additions & 3 deletions lib/omniauth/strategies/openid_connect.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class OpenIDConnect # rubocop:disable Metrics/ClassLength
scheme: 'https',
host: nil,
port: 443,
audience: nil,
authorization_endpoint: '/authorize',
token_endpoint: '/token',
userinfo_endpoint: '/userinfo',
Expand Down Expand Up @@ -470,9 +471,14 @@ def configured_response_type
def verify_id_token!(id_token)
return unless id_token

decode_id_token(id_token).verify!(issuer: options.issuer,
client_id: client_options.identifier,
nonce: params['nonce'].presence || stored_nonce)
verify_kwargs = {
issuer: options.issuer,
client_id: client_options.identifier,
nonce: params['nonce'].presence || stored_nonce,
}
verify_kwargs.merge!(audience: client_options.audience) if client_options.audience

decode_id_token(id_token).verify!(**verify_kwargs)
end

class CallbackError < StandardError
Expand Down
21 changes: 21 additions & 0 deletions test/lib/omniauth/strategies/openid_connect_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,27 @@ def test_callback_phase_with_id_token
strategy.callback_phase
end

def test_callback_phase_with_audience
state = SecureRandom.hex(16)
strategy.options.response_type = 'id_token'
strategy.options.issuer = 'example.com'
strategy.options.client_options.audience = 'my_audience'

id_token = stub('OpenIDConnect::ResponseObject::IdToken')
id_token.expects(:verify!).with(issuer: strategy.options.issuer, client_id: @identifier, audience: 'my_audience',
nonce: nonce).returns(true)
id_token.stubs(:raw_attributes, :to_h).returns(payload)

request.stubs(:params).returns('state' => state, 'nounce' => nonce, 'id_token' => id_token)
request.stubs(:path).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
end

def test_callback_phase_with_id_token_and_param_provided_nonce # rubocop:disable Metrics/AbcSize
code = SecureRandom.hex(16)
state = SecureRandom.hex(16)
Expand Down

0 comments on commit 23d4b13

Please sign in to comment.