omniauth_openid_connect 0.4.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +34 -2
- data/.rubocop.yml +1 -4
- data/CHANGELOG.md +13 -1
- data/Gemfile +6 -0
- data/README.md +31 -29
- data/Rakefile +2 -0
- data/lib/omniauth/openid_connect/version.rb +1 -1
- data/lib/omniauth/strategies/openid_connect.rb +132 -21
- data/omniauth_openid_connect.gemspec +2 -3
- data/test/lib/omniauth/strategies/openid_connect_test.rb +330 -66
- data/test/strategy_test_case.rb +47 -3
- data/test/test_helper.rb +17 -7
- metadata +24 -44
- data/.github/config/rubocop_linter_action.yml +0 -59
- data/.github/workflows/rubocop.yml +0 -22
- data/test/fixtures/id_token.txt +0 -1
- data/test/fixtures/jwks.json +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5ccd20bf84d71220597692301b64b1c3b0f8bf19faf1d788a6f1185bf42bfcb
|
4
|
+
data.tar.gz: 9336782a2449bfdefc07521f79bcd8030bf4cc2a6f094a01d9613dbcc21727f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 07b23acf7a852a2b5a1d7a4b6852108562fc7ce2c7f00ead2fe91989f00d736643c8e9f510ff8029956a0e55006d70b4671006ed4d2ca8a5c9a74f641a0c0e60
|
7
|
+
data.tar.gz: e22f6c174179f08acf046f05a50da341a01d576353a929fca9bd4c49f6d5ceaa5a761ce7ddaa4cfa6dae7470923bd0a646d634f6b7f563dca93df436c9b60a05
|
data/.github/workflows/main.yml
CHANGED
@@ -9,12 +9,12 @@ on:
|
|
9
9
|
types: [opened, synchronize, reopened]
|
10
10
|
|
11
11
|
jobs:
|
12
|
-
|
12
|
+
test:
|
13
13
|
runs-on: ubuntu-latest
|
14
14
|
strategy:
|
15
15
|
fail-fast: false
|
16
16
|
matrix:
|
17
|
-
ruby: ["2.5", "2.6", "2.7", "3.0"]
|
17
|
+
ruby: ["2.5", "2.6", "2.7", "3.0", "3.1"]
|
18
18
|
name: Ruby ${{ matrix.ruby }}
|
19
19
|
|
20
20
|
steps:
|
@@ -29,3 +29,35 @@ jobs:
|
|
29
29
|
|
30
30
|
- name: Run tests
|
31
31
|
run: bundle exec rake
|
32
|
+
|
33
|
+
- name: Coveralls Parallel
|
34
|
+
uses: coverallsapp/github-action@master
|
35
|
+
with:
|
36
|
+
github-token: ${{ secrets.github_token }}
|
37
|
+
flag-name: ruby-${{ matrix.ruby }}
|
38
|
+
parallel: true
|
39
|
+
|
40
|
+
finish:
|
41
|
+
needs: test
|
42
|
+
runs-on: ubuntu-latest
|
43
|
+
steps:
|
44
|
+
- name: Coveralls Finished
|
45
|
+
uses: coverallsapp/github-action@master
|
46
|
+
with:
|
47
|
+
github-token: ${{ secrets.github_token }}
|
48
|
+
parallel-finished: true
|
49
|
+
|
50
|
+
rubocop:
|
51
|
+
runs-on: ubuntu-latest
|
52
|
+
steps:
|
53
|
+
- name: Checkout code
|
54
|
+
uses: actions/checkout@v2
|
55
|
+
|
56
|
+
- name: Setup Ruby
|
57
|
+
uses: ruby/setup-ruby@v1
|
58
|
+
with:
|
59
|
+
bundler-cache: true
|
60
|
+
ruby-version: "2.7"
|
61
|
+
|
62
|
+
- name: rubocop
|
63
|
+
run: bundle exec rubocop --parallel
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,4 +1,16 @@
|
|
1
|
-
# v0.
|
1
|
+
# v0.6.0 (21.01.2023)
|
2
|
+
|
3
|
+
- Support verification of HS256-signed JWTs (https://github.com/omniauth/omniauth_openid_connect/pull/134)
|
4
|
+
|
5
|
+
# v0.5.0 (26.12.2022)
|
6
|
+
|
7
|
+
- Support the "nonce" parameter forwarding without a session [#130](https://github.com/omniauth/omniauth_openid_connect/pull/130)
|
8
|
+
- Fetch key from JWKS URI if available [#133](https://github.com/omniauth/omniauth_openid_connect/pull/133)
|
9
|
+
- Make the state parameter verification optional [#122](https://github.com/omniauth/omniauth_openid_connect/pull/122)
|
10
|
+
- Add email_verified claim in user info [#131](https://github.com/omniauth/omniauth_openid_connect/pull/131)
|
11
|
+
- Add PKCE verification support [#128](https://github.com/omniauth/omniauth_openid_connect/pull/128)
|
12
|
+
|
13
|
+
# v0.4.0 (06.02.2022)
|
2
14
|
|
3
15
|
- Support dynamic parameters to the authorize URI [#90](https://github.com/omniauth/omniauth_openid_connect/pull/90)
|
4
16
|
- Upgrade Faker and replace Travis with Github Actions [#102](https://github.com/omniauth/omniauth_openid_connect/pull/102)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,12 +1,3 @@
|
|
1
|
-
# Maintainers Wanted
|
2
|
-
|
3
|
-
This project is looking for maintainers.
|
4
|
-
|
5
|
-
Due to lack of using this gem in my projects I have no time to keep it alive.
|
6
|
-
Feel free to open an issue if you interested.
|
7
|
-
|
8
|
-
_This project is built and maintained 100% voluntarily._
|
9
|
-
|
10
1
|
# OmniAuth::OpenIDConnect
|
11
2
|
|
12
3
|
Originally was [omniauth-openid-connect](https://github.com/jjbohn/omniauth-openid-connect)
|
@@ -14,6 +5,7 @@ Originally was [omniauth-openid-connect](https://github.com/jjbohn/omniauth-open
|
|
14
5
|
I've forked this repository and launch as separate gem because maintaining of original was dropped.
|
15
6
|
|
16
7
|
[![Build Status](https://github.com/omniauth/omniauth_openid_connect/actions/workflows/main.yml/badge.svg)](https://github.com/omniauth/omniauth_openid_connect/actions/workflows/main.yml)
|
8
|
+
[![Coverage Status](https://coveralls.io/repos/github/omniauth/omniauth_openid_connect/badge.svg)](https://coveralls.io/github/omniauth/omniauth_openid_connect)
|
17
9
|
|
18
10
|
## Installation
|
19
11
|
|
@@ -31,7 +23,7 @@ Or install it yourself as:
|
|
31
23
|
|
32
24
|
## Supported Ruby Versions
|
33
25
|
|
34
|
-
OmniAuth::OpenIDConnect is tested under 2.
|
26
|
+
OmniAuth::OpenIDConnect is tested under 2.5, 2.6, 2.7, 3.0, 3.1
|
35
27
|
|
36
28
|
## Usage
|
37
29
|
|
@@ -55,24 +47,29 @@ config.omniauth :openid_connect, {
|
|
55
47
|
|
56
48
|
### Options Overview
|
57
49
|
|
58
|
-
| Field | Description | Required | Default
|
59
|
-
|
60
|
-
| name | Arbitrary string to identify connection and identify it from other openid_connect providers
|
61
|
-
| issuer | Root url for the authorization server | yes |
|
62
|
-
| discovery | Should OpenID discovery be used. This is recommended if the IDP provides a discovery endpoint. See client config for how to manually enter discovered values. | no | false
|
63
|
-
| client_auth_method | Which authentication method to use to authenticate your app with the authorization server | no | Sym: basic
|
64
|
-
| scope | Which OpenID scopes to include (:openid is always required) | no | Array<sym> [:openid]
|
65
|
-
| response_type | Which OAuth2 response type to use with the authorization request | no | String: code
|
66
|
-
| state | A value to be used for the OAuth2 state parameter on the authorization request. Can be a proc that generates a string. | no | Random 16 character string
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
50
|
+
| Field | Description | Required | Default | Example/Options |
|
51
|
+
|------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------|----------|-------------------------------|-----------------------------------------------------|
|
52
|
+
| name | Arbitrary string to identify connection and identify it from other openid_connect providers | no | String: openid_connect | :my_idp |
|
53
|
+
| issuer | Root url for the authorization server | yes | | https://myprovider.com |
|
54
|
+
| discovery | Should OpenID discovery be used. This is recommended if the IDP provides a discovery endpoint. See client config for how to manually enter discovered values. | no | false | one of: true, false |
|
55
|
+
| client_auth_method | Which authentication method to use to authenticate your app with the authorization server | no | Sym: basic | "basic", "jwks" |
|
56
|
+
| scope | Which OpenID scopes to include (:openid is always required) | no | Array<sym> [:openid] | [:openid, :profile, :email] |
|
57
|
+
| response_type | Which OAuth2 response type to use with the authorization request | no | String: code | one of: 'code', 'id_token' |
|
58
|
+
| state | A value to be used for the OAuth2 state parameter on the authorization request. Can be a proc that generates a string. | no | Random 16 character string | Proc.new { SecureRandom.hex(32) } |
|
59
|
+
| require_state | Should state param be verified - this is recommended, not required by the OIDC specification | no | true | false |
|
60
|
+
| response_mode | The response mode per [spec](https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html) | no | nil | one of: :query, :fragment, :form_post, :web_message |
|
61
|
+
| display | An optional parameter to the authorization request to determine how the authorization and consent page | no | nil | one of: :page, :popup, :touch, :wap |
|
62
|
+
| prompt | An optional parameter to the authrization request to determine what pages the user will be shown | no | nil | one of: :none, :login, :consent, :select_account |
|
63
|
+
| send_scope_to_token_endpoint | Should the scope parameter be sent to the authorization token endpoint? | no | true | one of: true, false |
|
64
|
+
| post_logout_redirect_uri | The logout redirect uri to use per the [session management draft](https://openid.net/specs/openid-connect-session-1_0.html) | no | empty | https://myapp.com/logout/callback |
|
65
|
+
| uid_field | The field of the user info response to be used as a unique id | no | 'sub' | "sub", "preferred_username" |
|
66
|
+
| extra_authorize_params | A hash of extra fixed parameters that will be merged to the authorization request | no | Hash | {"tenant" => "common"} |
|
67
|
+
| allow_authorize_params | A list of allowed dynamic parameters that will be merged to the authorization request | no | Array | [:screen_name] |
|
68
|
+
| pkce | Enable [PKCE flow](https://oauth.net/2/pkce/) | no | false | one of: true, false |
|
69
|
+
| pkce_verifier | Specify a custom PKCE verifier code. | no | A random 128-char string | Proc.new { SecureRandom.hex(64) } |
|
70
|
+
| pkce_options | Specify a custom implementation of the PKCE code challenge/method. | no | SHA256(code_challenge) in hex | Proc to customise the code challenge generation |
|
71
|
+
| client_options | A hash of client options detailed in its own section | yes | | |
|
72
|
+
| jwt_secret_base64 | For HMAC with SHA2 (e.g. HS256) signing algorithms, specify the base64-encoded secret used to sign the JWT token. Defaults to the OAuth2 client secret if not specified. | no | client_options.secret | "bXlzZWNyZXQ=\n"
|
76
73
|
|
77
74
|
### Client Config Options
|
78
75
|
|
@@ -102,7 +99,7 @@ These are the configuration options for the client_options hash of the configura
|
|
102
99
|
|
103
100
|
* `response_type` tells the authorization server which grant type the application wants to use,
|
104
101
|
currently, only `:code` (Authorization Code grant) and `:id_token` (Implicit grant) are valid.
|
105
|
-
* If you want to pass `state`
|
102
|
+
* If you want to pass `state` parameter by yourself. You can set Proc Object.
|
106
103
|
e.g. `state: Proc.new { SecureRandom.hex(32) }`
|
107
104
|
* `nonce` is optional. If don't want to pass "nonce" parameter to provider, You should specify
|
108
105
|
`false` to `send_nonce` option. (default true)
|
@@ -124,6 +121,11 @@ These are the configuration options for the client_options hash of the configura
|
|
124
121
|
property can be used to add the attribute to the token request. Initial value is `true`, which means that the
|
125
122
|
scope attribute is included by default.
|
126
123
|
|
124
|
+
## Additional notes
|
125
|
+
* 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.
|
126
|
+
In such example, the session is empty, so you have to forward certain parameters received from the client.
|
127
|
+
Currently supported ones are `code_verifier` and `nonce` - simply provide them as the `/callback` request parameters.
|
128
|
+
|
127
129
|
For the full low down on OpenID Connect, please check out
|
128
130
|
[the spec](http://openid.net/specs/openid-connect-core-1_0.html).
|
129
131
|
|
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'base64'
|
4
4
|
require 'timeout'
|
5
5
|
require 'net/http'
|
6
6
|
require 'open-uri'
|
@@ -10,7 +10,7 @@ require 'forwardable'
|
|
10
10
|
|
11
11
|
module OmniAuth
|
12
12
|
module Strategies
|
13
|
-
class OpenIDConnect
|
13
|
+
class OpenIDConnect # rubocop:disable Metrics/ClassLength
|
14
14
|
include OmniAuth::Strategy
|
15
15
|
extend Forwardable
|
16
16
|
|
@@ -37,10 +37,12 @@ module OmniAuth
|
|
37
37
|
option :issuer
|
38
38
|
option :discovery, false
|
39
39
|
option :client_signing_alg
|
40
|
+
option :jwt_secret_base64
|
40
41
|
option :client_jwk_signing_key
|
41
42
|
option :client_x509_signing_key
|
42
43
|
option :scope, [:openid]
|
43
44
|
option :response_type, 'code' # ['code', 'id_token']
|
45
|
+
option :require_state, true
|
44
46
|
option :state
|
45
47
|
option :response_mode # [:query, :fragment, :form_post, :web_message]
|
46
48
|
option :display, nil # [:page, :popup, :touch, :wap]
|
@@ -57,6 +59,14 @@ module OmniAuth
|
|
57
59
|
option :extra_authorize_params, {}
|
58
60
|
option :allow_authorize_params, []
|
59
61
|
option :uid_field, 'sub'
|
62
|
+
option :pkce, false
|
63
|
+
option :pkce_verifier, nil
|
64
|
+
option :pkce_options, {
|
65
|
+
code_challenge: proc { |verifier|
|
66
|
+
Base64.urlsafe_encode64(Digest::SHA2.digest(verifier), padding: false)
|
67
|
+
},
|
68
|
+
code_challenge_method: 'S256',
|
69
|
+
}
|
60
70
|
|
61
71
|
def uid
|
62
72
|
user_info.raw_attributes[options.uid_field.to_sym] || user_info.sub
|
@@ -66,6 +76,7 @@ module OmniAuth
|
|
66
76
|
{
|
67
77
|
name: user_info.name,
|
68
78
|
email: user_info.email,
|
79
|
+
email_verified: user_info.email_verified,
|
69
80
|
nickname: user_info.preferred_username,
|
70
81
|
first_name: user_info.given_name,
|
71
82
|
last_name: user_info.family_name,
|
@@ -107,7 +118,7 @@ module OmniAuth
|
|
107
118
|
def callback_phase
|
108
119
|
error = params['error_reason'] || params['error']
|
109
120
|
error_description = params['error_description'] || params['error_reason']
|
110
|
-
invalid_state = params['state'].to_s.empty? || params['state'] != stored_state
|
121
|
+
invalid_state = (options.require_state && params['state'].to_s.empty?) || params['state'] != stored_state
|
111
122
|
|
112
123
|
raise CallbackError, error: params['error'], reason: error_description, uri: params['error_uri'] if error
|
113
124
|
raise CallbackError, error: :csrf_detected, reason: "Invalid 'state' parameter" if invalid_state
|
@@ -178,17 +189,52 @@ module OmniAuth
|
|
178
189
|
opts[key] = request.params[key.to_s] unless opts.key?(key)
|
179
190
|
end
|
180
191
|
|
192
|
+
if options.pkce
|
193
|
+
verifier = options.pkce_verifier ? options.pkce_verifier.call : SecureRandom.hex(64)
|
194
|
+
|
195
|
+
opts.merge!(pkce_authorize_params(verifier))
|
196
|
+
session['omniauth.pkce.verifier'] = verifier
|
197
|
+
end
|
198
|
+
|
181
199
|
client.authorization_uri(opts.reject { |_k, v| v.nil? })
|
182
200
|
end
|
183
201
|
|
184
202
|
def public_key
|
185
|
-
|
203
|
+
@public_key ||= if options.discovery
|
204
|
+
config.jwks
|
205
|
+
elsif configured_public_key
|
206
|
+
configured_public_key
|
207
|
+
elsif client_options.jwks_uri
|
208
|
+
fetch_key
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
# Some OpenID providers use the OAuth2 client secret as the shared secret, but
|
213
|
+
# Keycloak uses a separate key that's stored inside the database.
|
214
|
+
def secret
|
215
|
+
base64_decoded_jwt_secret || client_options.secret
|
216
|
+
end
|
186
217
|
|
187
|
-
|
218
|
+
def pkce_authorize_params(verifier)
|
219
|
+
# NOTE: see https://tools.ietf.org/html/rfc7636#appendix-A
|
220
|
+
{
|
221
|
+
code_challenge: options.pkce_options[:code_challenge].call(verifier),
|
222
|
+
code_challenge_method: options.pkce_options[:code_challenge_method],
|
223
|
+
}
|
188
224
|
end
|
189
225
|
|
190
226
|
private
|
191
227
|
|
228
|
+
def fetch_key
|
229
|
+
@fetch_key ||= parse_jwk_key(::OpenIDConnect.http_client.get_content(client_options.jwks_uri))
|
230
|
+
end
|
231
|
+
|
232
|
+
def base64_decoded_jwt_secret
|
233
|
+
return unless options.jwt_secret_base64
|
234
|
+
|
235
|
+
Base64.decode64(options.jwt_secret_base64)
|
236
|
+
end
|
237
|
+
|
192
238
|
def issuer
|
193
239
|
resource = "#{ client_options.scheme }://#{ client_options.host }"
|
194
240
|
resource = "#{ resource }:#{ client_options.port }" if client_options.port
|
@@ -220,18 +266,88 @@ module OmniAuth
|
|
220
266
|
def access_token
|
221
267
|
return @access_token if @access_token
|
222
268
|
|
223
|
-
|
269
|
+
token_request_params = {
|
224
270
|
scope: (options.scope if options.send_scope_to_token_endpoint),
|
225
|
-
client_auth_method: options.client_auth_method
|
226
|
-
|
271
|
+
client_auth_method: options.client_auth_method,
|
272
|
+
}
|
227
273
|
|
274
|
+
token_request_params[:code_verifier] = params['code_verifier'] || session.delete('omniauth.pkce.verifier') if options.pkce
|
275
|
+
|
276
|
+
@access_token = client.access_token!(token_request_params)
|
228
277
|
verify_id_token!(@access_token.id_token) if configured_response_type == 'code'
|
229
278
|
|
230
279
|
@access_token
|
231
280
|
end
|
232
281
|
|
282
|
+
# Unlike ::OpenIDConnect::ResponseObject::IdToken.decode, this
|
283
|
+
# method splits the decoding and verification of JWT into two
|
284
|
+
# steps. First, we decode the JWT without verifying it to
|
285
|
+
# determine the algorithm used to sign. Then, we verify it using
|
286
|
+
# the appropriate public key (e.g. if algorithm is RS256) or
|
287
|
+
# shared secret (e.g. if algorithm is HS256). This works around a
|
288
|
+
# limitation in the openid_connect gem:
|
289
|
+
# https://github.com/nov/openid_connect/issues/61
|
233
290
|
def decode_id_token(id_token)
|
234
|
-
::
|
291
|
+
decoded = JSON::JWT.decode(id_token, :skip_verification)
|
292
|
+
algorithm = decoded.algorithm.to_sym
|
293
|
+
|
294
|
+
validate_client_algorithm!(algorithm)
|
295
|
+
|
296
|
+
keyset =
|
297
|
+
case algorithm
|
298
|
+
when :HS256, :HS384, :HS512
|
299
|
+
secret
|
300
|
+
else
|
301
|
+
public_key
|
302
|
+
end
|
303
|
+
|
304
|
+
decoded.verify!(keyset)
|
305
|
+
::OpenIDConnect::ResponseObject::IdToken.new(decoded)
|
306
|
+
rescue JSON::JWK::Set::KidNotFound
|
307
|
+
# If the JWT has a key ID (kid), then we know that the set of
|
308
|
+
# keys supplied doesn't contain the one we want, and we're
|
309
|
+
# done. However, if there is no kid, then we try each key
|
310
|
+
# individually to see if one works:
|
311
|
+
# https://github.com/nov/json-jwt/pull/92#issuecomment-824654949
|
312
|
+
raise if decoded&.header&.key?('kid')
|
313
|
+
|
314
|
+
decoded = decode_with_each_key!(id_token, keyset)
|
315
|
+
|
316
|
+
raise unless decoded
|
317
|
+
|
318
|
+
decoded
|
319
|
+
end
|
320
|
+
|
321
|
+
# If client_signing_alg is specified, we check that the returned JWT
|
322
|
+
# matches the expected algorithm. If not, we reject it.
|
323
|
+
def validate_client_algorithm!(algorithm)
|
324
|
+
client_signing_alg = options.client_signing_alg&.to_sym
|
325
|
+
|
326
|
+
return unless client_signing_alg
|
327
|
+
return if algorithm == client_signing_alg
|
328
|
+
|
329
|
+
reason = "Received JWT is signed with #{algorithm}, but client_singing_alg is configured for #{client_signing_alg}"
|
330
|
+
raise CallbackError, error: :invalid_jwt_algorithm, reason: reason, uri: params['error_uri']
|
331
|
+
end
|
332
|
+
|
333
|
+
def decode!(id_token, key)
|
334
|
+
::OpenIDConnect::ResponseObject::IdToken.decode(id_token, key)
|
335
|
+
end
|
336
|
+
|
337
|
+
def decode_with_each_key!(id_token, keyset)
|
338
|
+
return unless keyset.is_a?(JSON::JWK::Set)
|
339
|
+
|
340
|
+
keyset.each do |key|
|
341
|
+
begin
|
342
|
+
decoded = decode!(id_token, key)
|
343
|
+
rescue JSON::JWS::VerificationFailed, JSON::JWS::UnexpectedAlgorithm, JSON::JWS::UnknownAlgorithm
|
344
|
+
next
|
345
|
+
end
|
346
|
+
|
347
|
+
return decoded if decoded
|
348
|
+
end
|
349
|
+
|
350
|
+
nil
|
235
351
|
end
|
236
352
|
|
237
353
|
def client_options
|
@@ -273,17 +389,12 @@ module OmniAuth
|
|
273
389
|
super
|
274
390
|
end
|
275
391
|
|
276
|
-
def
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
parse_jwk_key(options.client_jwk_signing_key)
|
283
|
-
elsif options.client_x509_signing_key
|
284
|
-
parse_x509_key(options.client_x509_signing_key)
|
285
|
-
end
|
286
|
-
end
|
392
|
+
def configured_public_key
|
393
|
+
@configured_public_key ||= if options.client_jwk_signing_key
|
394
|
+
parse_jwk_key(options.client_jwk_signing_key)
|
395
|
+
elsif options.client_x509_signing_key
|
396
|
+
parse_x509_key(options.client_x509_signing_key)
|
397
|
+
end
|
287
398
|
end
|
288
399
|
|
289
400
|
def parse_x509_key(key)
|
@@ -353,7 +464,7 @@ module OmniAuth
|
|
353
464
|
|
354
465
|
decode_id_token(id_token).verify!(issuer: options.issuer,
|
355
466
|
client_id: client_options.identifier,
|
356
|
-
nonce: stored_nonce)
|
467
|
+
nonce: params['nonce'].presence || stored_nonce)
|
357
468
|
end
|
358
469
|
|
359
470
|
class CallbackError < StandardError
|
@@ -27,10 +27,8 @@ Gem::Specification.new do |spec|
|
|
27
27
|
'rubygems_mfa_required' => 'true',
|
28
28
|
}
|
29
29
|
|
30
|
-
spec.add_dependency 'addressable', '~> 2.5'
|
31
30
|
spec.add_dependency 'omniauth', '>= 1.9', '< 3'
|
32
31
|
spec.add_dependency 'openid_connect', '~> 1.1'
|
33
|
-
spec.add_development_dependency 'coveralls', '~> 0.8'
|
34
32
|
spec.add_development_dependency 'faker', '~> 2.0'
|
35
33
|
spec.add_development_dependency 'guard', '~> 2.14'
|
36
34
|
spec.add_development_dependency 'guard-bundler', '~> 2.2'
|
@@ -39,5 +37,6 @@ Gem::Specification.new do |spec|
|
|
39
37
|
spec.add_development_dependency 'mocha', '~> 1.7'
|
40
38
|
spec.add_development_dependency 'rake', '~> 12.0'
|
41
39
|
spec.add_development_dependency 'rubocop', '~> 1.12'
|
42
|
-
spec.add_development_dependency 'simplecov', '~> 0.
|
40
|
+
spec.add_development_dependency 'simplecov', '~> 0.21'
|
41
|
+
spec.add_development_dependency 'simplecov-lcov', '~> 0.8'
|
43
42
|
end
|