googleauth 0.9.0 → 0.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +11 -0
  3. data/CHANGELOG.md +113 -21
  4. data/README.md +13 -15
  5. data/SECURITY.md +7 -0
  6. data/lib/googleauth/application_default.rb +9 -9
  7. data/lib/googleauth/compute_engine.rb +55 -30
  8. data/lib/googleauth/credentials.rb +253 -64
  9. data/lib/googleauth/credentials_loader.rb +15 -16
  10. data/lib/googleauth/iam.rb +1 -1
  11. data/{spec/googleauth/stores/store_examples.rb → lib/googleauth/id_tokens/errors.rb} +36 -23
  12. data/lib/googleauth/id_tokens/key_sources.rb +396 -0
  13. data/lib/googleauth/id_tokens/verifier.rb +142 -0
  14. data/lib/googleauth/id_tokens.rb +233 -0
  15. data/lib/googleauth/json_key_reader.rb +6 -2
  16. data/lib/googleauth/scope_util.rb +1 -1
  17. data/lib/googleauth/service_account.rb +61 -36
  18. data/lib/googleauth/signet.rb +9 -7
  19. data/lib/googleauth/stores/file_token_store.rb +1 -0
  20. data/lib/googleauth/stores/redis_token_store.rb +1 -0
  21. data/lib/googleauth/user_authorizer.rb +8 -3
  22. data/lib/googleauth/user_refresh.rb +1 -1
  23. data/lib/googleauth/version.rb +1 -1
  24. data/lib/googleauth/web_user_authorizer.rb +5 -8
  25. data/lib/googleauth.rb +1 -0
  26. metadata +33 -76
  27. data/.github/CONTRIBUTING.md +0 -74
  28. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -36
  29. data/.github/ISSUE_TEMPLATE/feature_request.md +0 -21
  30. data/.github/ISSUE_TEMPLATE/support_request.md +0 -7
  31. data/.gitignore +0 -36
  32. data/.kokoro/build.bat +0 -16
  33. data/.kokoro/build.sh +0 -4
  34. data/.kokoro/continuous/common.cfg +0 -24
  35. data/.kokoro/continuous/linux.cfg +0 -15
  36. data/.kokoro/continuous/osx.cfg +0 -3
  37. data/.kokoro/continuous/windows.cfg +0 -19
  38. data/.kokoro/osx.sh +0 -4
  39. data/.kokoro/presubmit/common.cfg +0 -24
  40. data/.kokoro/presubmit/linux.cfg +0 -14
  41. data/.kokoro/presubmit/osx.cfg +0 -3
  42. data/.kokoro/presubmit/windows.cfg +0 -19
  43. data/.kokoro/release.cfg +0 -53
  44. data/.kokoro/trampoline.bat +0 -10
  45. data/.kokoro/trampoline.sh +0 -4
  46. data/.rspec +0 -2
  47. data/.rubocop.yml +0 -42
  48. data/Gemfile +0 -25
  49. data/Rakefile +0 -89
  50. data/googleauth.gemspec +0 -35
  51. data/spec/googleauth/apply_auth_examples.rb +0 -148
  52. data/spec/googleauth/client_id_spec.rb +0 -160
  53. data/spec/googleauth/compute_engine_spec.rb +0 -122
  54. data/spec/googleauth/credentials_spec.rb +0 -459
  55. data/spec/googleauth/get_application_default_spec.rb +0 -286
  56. data/spec/googleauth/iam_spec.rb +0 -80
  57. data/spec/googleauth/scope_util_spec.rb +0 -77
  58. data/spec/googleauth/service_account_spec.rb +0 -482
  59. data/spec/googleauth/signet_spec.rb +0 -134
  60. data/spec/googleauth/stores/file_token_store_spec.rb +0 -57
  61. data/spec/googleauth/stores/redis_token_store_spec.rb +0 -50
  62. data/spec/googleauth/user_authorizer_spec.rb +0 -323
  63. data/spec/googleauth/user_refresh_spec.rb +0 -359
  64. data/spec/googleauth/web_user_authorizer_spec.rb +0 -172
  65. data/spec/spec_helper.rb +0 -92
  66. /data/{COPYING → LICENSE} +0 -0
@@ -0,0 +1,396 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2020 Google LLC
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are
7
+ # met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # * Redistributions in binary form must reproduce the above
12
+ # copyright notice, this list of conditions and the following disclaimer
13
+ # in the documentation and/or other materials provided with the
14
+ # distribution.
15
+ # * Neither the name of Google Inc. nor the names of its
16
+ # contributors may be used to endorse or promote products derived from
17
+ # this software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ require "base64"
32
+ require "json"
33
+ require "monitor"
34
+ require "net/http"
35
+ require "openssl"
36
+
37
+ require "jwt"
38
+
39
+ module Google
40
+ module Auth
41
+ module IDTokens
42
+ ##
43
+ # A public key used for verifying ID tokens.
44
+ #
45
+ # This includes the public key data, ID, and the algorithm used for
46
+ # signature verification. RSA and Elliptical Curve (EC) keys are
47
+ # supported.
48
+ #
49
+ class KeyInfo
50
+ ##
51
+ # Create a public key info structure.
52
+ #
53
+ # @param id [String] The key ID.
54
+ # @param key [OpenSSL::PKey::RSA,OpenSSL::PKey::EC] The key itself.
55
+ # @param algorithm [String] The algorithm (normally `RS256` or `ES256`)
56
+ #
57
+ def initialize id: nil, key: nil, algorithm: nil
58
+ @id = id
59
+ @key = key
60
+ @algorithm = algorithm
61
+ end
62
+
63
+ ##
64
+ # The key ID.
65
+ # @return [String]
66
+ #
67
+ attr_reader :id
68
+
69
+ ##
70
+ # The key itself.
71
+ # @return [OpenSSL::PKey::RSA,OpenSSL::PKey::EC]
72
+ #
73
+ attr_reader :key
74
+
75
+ ##
76
+ # The signature algorithm. (normally `RS256` or `ES256`)
77
+ # @return [String]
78
+ #
79
+ attr_reader :algorithm
80
+
81
+ class << self
82
+ ##
83
+ # Create a KeyInfo from a single JWK, which may be given as either a
84
+ # hash or an unparsed JSON string.
85
+ #
86
+ # @param jwk [Hash,String] The JWK specification.
87
+ # @return [KeyInfo]
88
+ # @raise [KeySourceError] If the key could not be extracted from the
89
+ # JWK.
90
+ #
91
+ def from_jwk jwk
92
+ jwk = symbolize_keys ensure_json_parsed jwk
93
+ key = case jwk[:kty]
94
+ when "RSA"
95
+ extract_rsa_key jwk
96
+ when "EC"
97
+ extract_ec_key jwk
98
+ when nil
99
+ raise KeySourceError, "Key type not found"
100
+ else
101
+ raise KeySourceError, "Cannot use key type #{jwk[:kty]}"
102
+ end
103
+ new id: jwk[:kid], key: key, algorithm: jwk[:alg]
104
+ end
105
+
106
+ ##
107
+ # Create an array of KeyInfo from a JWK Set, which may be given as
108
+ # either a hash or an unparsed JSON string.
109
+ #
110
+ # @param jwk [Hash,String] The JWK Set specification.
111
+ # @return [Array<KeyInfo>]
112
+ # @raise [KeySourceError] If a key could not be extracted from the
113
+ # JWK Set.
114
+ #
115
+ def from_jwk_set jwk_set
116
+ jwk_set = symbolize_keys ensure_json_parsed jwk_set
117
+ jwks = jwk_set[:keys]
118
+ raise KeySourceError, "No keys found in jwk set" unless jwks
119
+ jwks.map { |jwk| from_jwk jwk }
120
+ end
121
+
122
+ private
123
+
124
+ def ensure_json_parsed input
125
+ return input unless input.is_a? String
126
+ JSON.parse input
127
+ rescue JSON::ParserError
128
+ raise KeySourceError, "Unable to parse JSON"
129
+ end
130
+
131
+ def symbolize_keys hash
132
+ result = {}
133
+ hash.each { |key, val| result[key.to_sym] = val }
134
+ result
135
+ end
136
+
137
+ def extract_rsa_key jwk
138
+ begin
139
+ n_data = Base64.urlsafe_decode64 jwk[:n]
140
+ e_data = Base64.urlsafe_decode64 jwk[:e]
141
+ rescue ArgumentError
142
+ raise KeySourceError, "Badly formatted key data"
143
+ end
144
+ n_bn = OpenSSL::BN.new n_data, 2
145
+ e_bn = OpenSSL::BN.new e_data, 2
146
+ rsa_key = OpenSSL::PKey::RSA.new
147
+ if rsa_key.respond_to? :set_key
148
+ rsa_key.set_key n_bn, e_bn, nil
149
+ else
150
+ rsa_key.n = n_bn
151
+ rsa_key.e = e_bn
152
+ end
153
+ rsa_key.public_key
154
+ end
155
+
156
+ # @private
157
+ CURVE_NAME_MAP = {
158
+ "P-256" => "prime256v1",
159
+ "P-384" => "secp384r1",
160
+ "P-521" => "secp521r1",
161
+ "secp256k1" => "secp256k1"
162
+ }.freeze
163
+
164
+ def extract_ec_key jwk
165
+ begin
166
+ x_data = Base64.urlsafe_decode64 jwk[:x]
167
+ y_data = Base64.urlsafe_decode64 jwk[:y]
168
+ rescue ArgumentError
169
+ raise KeySourceError, "Badly formatted key data"
170
+ end
171
+ curve_name = CURVE_NAME_MAP[jwk[:crv]]
172
+ raise KeySourceError, "Unsupported EC curve #{jwk[:crv]}" unless curve_name
173
+ group = OpenSSL::PKey::EC::Group.new curve_name
174
+ x_hex = x_data.unpack1 "H*"
175
+ y_hex = y_data.unpack1 "H*"
176
+ bn = OpenSSL::BN.new ["04#{x_hex}#{y_hex}"].pack("H*"), 2
177
+ key = OpenSSL::PKey::EC.new curve_name
178
+ key.public_key = OpenSSL::PKey::EC::Point.new group, bn
179
+ key
180
+ end
181
+ end
182
+ end
183
+
184
+ ##
185
+ # A key source that contains a static set of keys.
186
+ #
187
+ class StaticKeySource
188
+ ##
189
+ # Create a static key source with the given keys.
190
+ #
191
+ # @param keys [Array<KeyInfo>] The keys
192
+ #
193
+ def initialize keys
194
+ @current_keys = Array(keys)
195
+ end
196
+
197
+ ##
198
+ # Return the current keys. Does not perform any refresh.
199
+ #
200
+ # @return [Array<KeyInfo>]
201
+ #
202
+ attr_reader :current_keys
203
+ alias refresh_keys current_keys
204
+
205
+ class << self
206
+ ##
207
+ # Create a static key source containing a single key parsed from a
208
+ # single JWK, which may be given as either a hash or an unparsed
209
+ # JSON string.
210
+ #
211
+ # @param jwk [Hash,String] The JWK specification.
212
+ # @return [StaticKeySource]
213
+ #
214
+ def from_jwk jwk
215
+ new KeyInfo.from_jwk jwk
216
+ end
217
+
218
+ ##
219
+ # Create a static key source containing multiple keys parsed from a
220
+ # JWK Set, which may be given as either a hash or an unparsed JSON
221
+ # string.
222
+ #
223
+ # @param jwk_set [Hash,String] The JWK Set specification.
224
+ # @return [StaticKeySource]
225
+ #
226
+ def from_jwk_set jwk_set
227
+ new KeyInfo.from_jwk_set jwk_set
228
+ end
229
+ end
230
+ end
231
+
232
+ ##
233
+ # A base key source that downloads keys from a URI. Subclasses should
234
+ # override {HttpKeySource#interpret_json} to parse the response.
235
+ #
236
+ class HttpKeySource
237
+ ##
238
+ # The default interval between retries in seconds (3600s = 1hr).
239
+ #
240
+ # @return [Integer]
241
+ #
242
+ DEFAULT_RETRY_INTERVAL = 3600
243
+
244
+ ##
245
+ # Create an HTTP key source.
246
+ #
247
+ # @param uri [String,URI] The URI from which to download keys.
248
+ # @param retry_interval [Integer,nil] Override the retry interval in
249
+ # seconds. This is the minimum time between retries of failed key
250
+ # downloads.
251
+ #
252
+ def initialize uri, retry_interval: nil
253
+ @uri = URI uri
254
+ @retry_interval = retry_interval || DEFAULT_RETRY_INTERVAL
255
+ @allow_refresh_at = Time.now
256
+ @current_keys = []
257
+ @monitor = Monitor.new
258
+ end
259
+
260
+ ##
261
+ # The URI from which to download keys.
262
+ # @return [Array<KeyInfo>]
263
+ #
264
+ attr_reader :uri
265
+
266
+ ##
267
+ # Return the current keys, without attempting to re-download.
268
+ #
269
+ # @return [Array<KeyInfo>]
270
+ #
271
+ attr_reader :current_keys
272
+
273
+ ##
274
+ # Attempt to re-download keys (if the retry interval has expired) and
275
+ # return the new keys.
276
+ #
277
+ # @return [Array<KeyInfo>]
278
+ # @raise [KeySourceError] if key retrieval failed.
279
+ #
280
+ def refresh_keys
281
+ @monitor.synchronize do
282
+ return @current_keys if Time.now < @allow_refresh_at
283
+ @allow_refresh_at = Time.now + @retry_interval
284
+
285
+ response = Net::HTTP.get_response uri
286
+ raise KeySourceError, "Unable to retrieve data from #{uri}" unless response.is_a? Net::HTTPSuccess
287
+
288
+ data = begin
289
+ JSON.parse response.body
290
+ rescue JSON::ParserError
291
+ raise KeySourceError, "Unable to parse JSON"
292
+ end
293
+
294
+ @current_keys = Array(interpret_json(data))
295
+ end
296
+ end
297
+
298
+ protected
299
+
300
+ def interpret_json _data
301
+ nil
302
+ end
303
+ end
304
+
305
+ ##
306
+ # A key source that downloads X509 certificates.
307
+ # Used by the legacy OAuth V1 public certs endpoint.
308
+ #
309
+ class X509CertHttpKeySource < HttpKeySource
310
+ ##
311
+ # Create a key source that downloads X509 certificates.
312
+ #
313
+ # @param uri [String,URI] The URI from which to download keys.
314
+ # @param algorithm [String] The algorithm to use for signature
315
+ # verification. Defaults to "`RS256`".
316
+ # @param retry_interval [Integer,nil] Override the retry interval in
317
+ # seconds. This is the minimum time between retries of failed key
318
+ # downloads.
319
+ #
320
+ def initialize uri, algorithm: "RS256", retry_interval: nil
321
+ super uri, retry_interval: retry_interval
322
+ @algorithm = algorithm
323
+ end
324
+
325
+ protected
326
+
327
+ def interpret_json data
328
+ data.map do |id, cert_str|
329
+ key = OpenSSL::X509::Certificate.new(cert_str).public_key
330
+ KeyInfo.new id: id, key: key, algorithm: @algorithm
331
+ end
332
+ rescue OpenSSL::X509::CertificateError
333
+ raise KeySourceError, "Unable to parse X509 certificates"
334
+ end
335
+ end
336
+
337
+ ##
338
+ # A key source that downloads a JWK set.
339
+ #
340
+ class JwkHttpKeySource < HttpKeySource
341
+ ##
342
+ # Create a key source that downloads a JWT Set.
343
+ #
344
+ # @param uri [String,URI] The URI from which to download keys.
345
+ # @param retry_interval [Integer,nil] Override the retry interval in
346
+ # seconds. This is the minimum time between retries of failed key
347
+ # downloads.
348
+ #
349
+ def initialize uri, retry_interval: nil
350
+ super uri, retry_interval: retry_interval
351
+ end
352
+
353
+ protected
354
+
355
+ def interpret_json data
356
+ KeyInfo.from_jwk_set data
357
+ end
358
+ end
359
+
360
+ ##
361
+ # A key source that aggregates other key sources. This means it will
362
+ # aggregate the keys provided by its constituent sources. Additionally,
363
+ # when asked to refresh, it will refresh all its constituent sources.
364
+ #
365
+ class AggregateKeySource
366
+ ##
367
+ # Create a key source that aggregates other key sources.
368
+ #
369
+ # @param sources [Array<key source>] The key sources to aggregate.
370
+ #
371
+ def initialize sources
372
+ @sources = Array(sources)
373
+ end
374
+
375
+ ##
376
+ # Return the current keys, without attempting to refresh.
377
+ #
378
+ # @return [Array<KeyInfo>]
379
+ #
380
+ def current_keys
381
+ @sources.flat_map(&:current_keys)
382
+ end
383
+
384
+ ##
385
+ # Attempt to refresh keys and return the new keys.
386
+ #
387
+ # @return [Array<KeyInfo>]
388
+ # @raise [KeySourceError] if key retrieval failed.
389
+ #
390
+ def refresh_keys
391
+ @sources.flat_map(&:refresh_keys)
392
+ end
393
+ end
394
+ end
395
+ end
396
+ end
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2020 Google LLC
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are
7
+ # met:
8
+ #
9
+ # * Redistributions of source code must retain the above copyright
10
+ # notice, this list of conditions and the following disclaimer.
11
+ # * Redistributions in binary form must reproduce the above
12
+ # copyright notice, this list of conditions and the following disclaimer
13
+ # in the documentation and/or other materials provided with the
14
+ # distribution.
15
+ # * Neither the name of Google Inc. nor the names of its
16
+ # contributors may be used to endorse or promote products derived from
17
+ # this software without specific prior written permission.
18
+ #
19
+ # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20
+ # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21
+ # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22
+ # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23
+ # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24
+ # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25
+ # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26
+ # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27
+ # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29
+ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+
31
+ require "jwt"
32
+
33
+ module Google
34
+ module Auth
35
+ module IDTokens
36
+ ##
37
+ # An object that can verify ID tokens.
38
+ #
39
+ # A verifier maintains a set of default settings, including the key
40
+ # source and fields to verify. However, individual verification calls can
41
+ # override any of these settings.
42
+ #
43
+ class Verifier
44
+ ##
45
+ # Create a verifier.
46
+ #
47
+ # @param key_source [key source] The default key source to use. All
48
+ # verification calls must have a key source, so if no default key
49
+ # source is provided here, then calls to {#verify} _must_ provide
50
+ # a key source.
51
+ # @param aud [String,nil] The default audience (`aud`) check, or `nil`
52
+ # for no check.
53
+ # @param azp [String,nil] The default authorized party (`azp`) check,
54
+ # or `nil` for no check.
55
+ # @param iss [String,nil] The default issuer (`iss`) check, or `nil`
56
+ # for no check.
57
+ #
58
+ def initialize key_source: nil,
59
+ aud: nil,
60
+ azp: nil,
61
+ iss: nil
62
+ @key_source = key_source
63
+ @aud = aud
64
+ @azp = azp
65
+ @iss = iss
66
+ end
67
+
68
+ ##
69
+ # Verify the given token.
70
+ #
71
+ # @param token [String] the ID token to verify.
72
+ # @param key_source [key source] If given, override the key source.
73
+ # @param aud [String,nil] If given, override the `aud` check.
74
+ # @param azp [String,nil] If given, override the `azp` check.
75
+ # @param iss [String,nil] If given, override the `iss` check.
76
+ #
77
+ # @return [Hash] the decoded payload, if verification succeeded.
78
+ # @raise [KeySourceError] if the key source failed to obtain public keys
79
+ # @raise [VerificationError] if the token verification failed.
80
+ # Additional data may be available in the error subclass and message.
81
+ #
82
+ def verify token,
83
+ key_source: :default,
84
+ aud: :default,
85
+ azp: :default,
86
+ iss: :default
87
+ key_source = @key_source if key_source == :default
88
+ aud = @aud if aud == :default
89
+ azp = @azp if azp == :default
90
+ iss = @iss if iss == :default
91
+
92
+ raise KeySourceError, "No key sources" unless key_source
93
+ keys = key_source.current_keys
94
+ payload = decode_token token, keys, aud, azp, iss
95
+ unless payload
96
+ keys = key_source.refresh_keys
97
+ payload = decode_token token, keys, aud, azp, iss
98
+ end
99
+ raise SignatureError, "Token not verified as issued by Google" unless payload
100
+ payload
101
+ end
102
+
103
+ private
104
+
105
+ def decode_token token, keys, aud, azp, iss
106
+ payload = nil
107
+ keys.find do |key|
108
+ options = { algorithms: key.algorithm }
109
+ decoded_token = JWT.decode token, key.key, true, options
110
+ payload = decoded_token.first
111
+ rescue JWT::ExpiredSignature
112
+ raise ExpiredTokenError, "Token signature is expired"
113
+ rescue JWT::DecodeError
114
+ nil # Try the next key
115
+ end
116
+
117
+ normalize_and_verify_payload payload, aud, azp, iss
118
+ end
119
+
120
+ def normalize_and_verify_payload payload, aud, azp, iss
121
+ return nil unless payload
122
+
123
+ # Map the legacy "cid" claim to the canonical "azp"
124
+ payload["azp"] ||= payload["cid"] if payload.key? "cid"
125
+
126
+ # Payload content validation
127
+ if aud && (Array(aud) & Array(payload["aud"])).empty?
128
+ raise AudienceMismatchError, "Token aud mismatch: #{payload['aud']}"
129
+ end
130
+ if azp && (Array(azp) & Array(payload["azp"])).empty?
131
+ raise AuthorizedPartyMismatchError, "Token azp mismatch: #{payload['azp']}"
132
+ end
133
+ if iss && (Array(iss) & Array(payload["iss"])).empty?
134
+ raise IssuerMismatchError, "Token iss mismatch: #{payload['iss']}"
135
+ end
136
+
137
+ payload
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end