Skip to content

Commit 0798613

Browse files
skycockerstanhu
authored andcommitted
Support the "nonce" parameter forwarding without a session
1 parent 147b0ab commit 0798613

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,10 @@ These are the configuration options for the client_options hash of the configura
120120
property can be used to add the attribute to the token request. Initial value is `true`, which means that the
121121
scope attribute is included by default.
122122

123-
### Additional notes
123+
## Additional notes
124124
* In some cases, you may want to go straight to the callback phase - e.g. when requested by a stateless client, like a mobile app.
125125
In such example, the session is empty, so you have to forward certain parameters received from the client.
126-
Currently supported one is `code_verifier` - simply provide it as the `/callback` request parameter.
126+
Currently supported ones are `code_verifier` and `nonce` - simply provide them as the `/callback` request parameters.
127127

128128
For the full low down on OpenID Connect, please check out
129129
[the spec](http://openid.net/specs/openid-connect-core-1_0.html).

lib/omniauth/strategies/openid_connect.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ def verify_id_token!(id_token)
389389

390390
decode_id_token(id_token).verify!(issuer: options.issuer,
391391
client_id: client_options.identifier,
392-
nonce: stored_nonce)
392+
nonce: params['nonce'].presence || stored_nonce)
393393
end
394394

395395
class CallbackError < StandardError

test/lib/omniauth/strategies/openid_connect_test.rb

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,38 @@ def test_callback_phase_with_id_token
237237
strategy.callback_phase
238238
end
239239

240+
def test_callback_phase_with_id_token_and_param_provided_nonce # rubocop:disable Metrics/AbcSize
241+
code = SecureRandom.hex(16)
242+
state = SecureRandom.hex(16)
243+
nonce = SecureRandom.hex(16)
244+
request.stubs(:params).returns('code' => code, 'state' => state, 'nonce' => nonce)
245+
request.stubs(:path).returns('')
246+
247+
strategy.options.issuer = 'example.com'
248+
strategy.options.client_signing_alg = :RS256
249+
strategy.options.client_jwk_signing_key = jwks.to_s
250+
strategy.options.response_type = 'code'
251+
252+
strategy.unstub(:user_info)
253+
access_token = stub('OpenIDConnect::AccessToken')
254+
access_token.stubs(:access_token)
255+
access_token.stubs(:refresh_token)
256+
access_token.stubs(:expires_in)
257+
access_token.stubs(:scope)
258+
access_token.stubs(:id_token).returns(jwt.to_s)
259+
client.expects(:access_token!).at_least_once.returns(access_token)
260+
access_token.expects(:userinfo!).returns(user_info)
261+
262+
id_token = stub('OpenIDConnect::ResponseObject::IdToken')
263+
id_token.stubs(:raw_attributes).returns('sub' => 'sub', 'name' => 'name', 'email' => 'email')
264+
id_token.stubs(:verify!).with(issuer: strategy.options.issuer, client_id: @identifier, nonce: nonce).returns(true)
265+
id_token.expects(:verify!)
266+
267+
strategy.expects(:decode_id_token).twice.with(access_token.id_token).returns(id_token)
268+
strategy.call!('rack.session' => { 'omniauth.state' => state })
269+
strategy.callback_phase
270+
end
271+
240272
def test_callback_phase_with_discovery # rubocop:disable Metrics/AbcSize
241273
state = SecureRandom.hex(16)
242274

0 commit comments

Comments
 (0)