jwt 2.9.0 → 2.9.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +45 -1
- data/README.md +19 -1
- data/lib/jwt/claims/decode_verifier.rb +40 -0
- data/lib/jwt/claims/numeric.rb +25 -13
- data/lib/jwt/claims/verifier.rb +62 -0
- data/lib/jwt/claims.rb +60 -16
- data/lib/jwt/claims_validator.rb +15 -0
- data/lib/jwt/decode.rb +2 -1
- data/lib/jwt/encode.rb +1 -1
- data/lib/jwt/jwa/compat.rb +29 -0
- data/lib/jwt/jwa/ecdsa.rb +4 -0
- data/lib/jwt/jwa/hmac.rb +4 -0
- data/lib/jwt/jwa/hmac_rbnacl.rb +4 -0
- data/lib/jwt/jwa/hmac_rbnacl_fixed.rb +4 -0
- data/lib/jwt/jwa/signing_algorithm.rb +1 -0
- data/lib/jwt/jwa.rb +6 -1
- data/lib/jwt/verify.rb +33 -0
- data/lib/jwt/version.rb +1 -1
- data/lib/jwt.rb +3 -0
- metadata +8 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: bd2c497012269d18de9e39316124f41be2e7b095fa25068f4eb1a9e82ce74bcb
|
4
|
+
data.tar.gz: ae2c8d4ad25c8c49aa00c7c3e75ff80fab5eb59be7b76cb9ee4e272200e53b30
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 20ffc73333a32ef4ff3c15972f9487b16cb191fadd9980ae1895b4a0a2ce3074a5d51e2183b36aa98abd3b1e9822f2546e20fc39dd60d193c08e9f30a3329624
|
7
|
+
data.tar.gz: 1500f0aef9ba50725c8090021ad5be31e100733a502e069c93b6caa6fce58b0e0b48704cccf0efab7e868655a572ba65eb7c96681f9f184bd0337515bb847966
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,50 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
-
##
|
3
|
+
## Upcoming breaking changes
|
4
|
+
|
5
|
+
Notable changes in the upcoming **version 3.0**:
|
6
|
+
|
7
|
+
- The indirect dependency to [rbnacl](https://github.com/RubyCrypto/rbnacl) will be removed:
|
8
|
+
- Support for the nonstandard SHA512256 algorithm will be removed.
|
9
|
+
- Support for Ed25519 will be moved to a [separate gem](https://github.com/anakinj/jwt-eddsa) for better dependency handling.
|
10
|
+
|
11
|
+
- Base64 decoding will no longer fallback on the looser RFC 2045.
|
12
|
+
|
13
|
+
- Claim verification has been [split into separate classes](https://github.com/jwt/ruby-jwt/pull/605) and has [a new api](https://github.com/jwt/ruby-jwt/pull/626) and lead to the following deprecations:
|
14
|
+
- The `::JWT::ClaimsValidator` class will be removed in favor of the functionality provided by `::JWT::Claims`.
|
15
|
+
- The `::JWT::Claims::verify!` method will be removed in favor of `::JWT::Claims::verify_payload!`.
|
16
|
+
- The `::JWT::JWA.create` method will be removed. No recommended alternatives.
|
17
|
+
- The `::JWT::Verify` class will be removed in favor of the functionality provided by `::JWT::Claims`.
|
18
|
+
- Calling `::JWT::Claims::Numeric.new` with a payload will be removed in favor of `::JWT::Claims::verify_payload!(payload, :numeric)`
|
19
|
+
- Calling `::JWT::Claims::Numeric.verify!` with a payload will be removed in favor of `::JWT::Claims::verify_payload!(payload, :numeric)`
|
20
|
+
|
21
|
+
- The internal algorithms were [restructured](https://github.com/jwt/ruby-jwt/pull/607) to support extensions from separate libraries. The changes lead to a few deprecations and new requirements:
|
22
|
+
- The `sign` and `verify` static methods on all the algorithms (`::JWT::JWA`) will be removed.
|
23
|
+
- Custom algorithms are expected to include the `JWT::JWA::SigningAlgorithm` module.
|
24
|
+
|
25
|
+
## [v2.9.2](https://github.com/jwt/ruby-jwt/tree/v2.9.2) (2024-10-03)
|
26
|
+
|
27
|
+
[Full Changelog](https://github.com/jwt/ruby-jwt/compare/v2.9.1...v2.9.2)
|
28
|
+
|
29
|
+
**Features:**
|
30
|
+
|
31
|
+
- Standalone claim verification interface [#626](https://github.com/jwt/ruby-jwt/pull/626) ([@anakinj](https://github.com/anakinj))
|
32
|
+
|
33
|
+
**Fixes and enhancements:**
|
34
|
+
|
35
|
+
- Updated README to correctly document `OpenSSL::HMAC` documentation [#617](https://github.com/jwt/ruby-jwt/pull/617) ([@aedryan](https://github.com/aedryan))
|
36
|
+
- Verify JWT header format [#622](https://github.com/jwt/ruby-jwt/pull/622) ([@304](https://github.com/304))
|
37
|
+
- Bring back `::JWT::ClaimsValidator`, `::JWT::Verify` and a few other removed interfaces for preserved backwards compatibility [#624](https://github.com/jwt/ruby-jwt/pull/624) ([@anakinj](https://github.com/anakinj))
|
38
|
+
|
39
|
+
## [v2.9.1](https://github.com/jwt/ruby-jwt/tree/v2.9.1) (2024-09-23)
|
40
|
+
|
41
|
+
[Full Changelog](https://github.com/jwt/ruby-jwt/compare/v2.9.0...v2.9.1)
|
42
|
+
|
43
|
+
**Fixes and enhancements:**
|
44
|
+
|
45
|
+
- Fix regression in `iss` and `aud` claim validation [#619](https://github.com/jwt/ruby-jwt/pull/619) ([@anakinj](https://github.com/anakinj))
|
46
|
+
|
47
|
+
## [v2.9.0](https://github.com/jwt/ruby-jwt/tree/v2.9.0) (2024-09-15)
|
4
48
|
|
5
49
|
[Full Changelog](https://github.com/jwt/ruby-jwt/compare/v2.8.2...v2.9.0)
|
6
50
|
|
data/README.md
CHANGED
@@ -240,7 +240,7 @@ module CustomHS512Algorithm
|
|
240
240
|
end
|
241
241
|
|
242
242
|
def self.sign(data:, signing_key:)
|
243
|
-
OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha512'),
|
243
|
+
OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha512'), signing_key, data)
|
244
244
|
end
|
245
245
|
|
246
246
|
def self.verify(data:, signature:, verification_key:)
|
@@ -530,6 +530,24 @@ rescue JWT::InvalidSubError
|
|
530
530
|
end
|
531
531
|
```
|
532
532
|
|
533
|
+
### Standalone claim verification
|
534
|
+
|
535
|
+
The JWT claim verifications can be used to verify any Hash to include expected keys and values.
|
536
|
+
|
537
|
+
A few example on verifying the claims for a payload:
|
538
|
+
```ruby
|
539
|
+
JWT::Claims.verify_payload!({"exp" => Time.now.to_i + 10}, :numeric, :exp)
|
540
|
+
JWT::Claims.valid_payload?({"exp" => Time.now.to_i + 10}, :exp)
|
541
|
+
# => true
|
542
|
+
JWT::Claims.payload_errors({"exp" => Time.now.to_i - 10}, :exp)
|
543
|
+
# => [#<struct JWT::Claims::Error message="Signature has expired">]
|
544
|
+
JWT::Claims.verify_payload!({"exp" => Time.now.to_i - 10}, exp: { leeway: 11})
|
545
|
+
|
546
|
+
JWT::Claims.verify_payload!({"exp" => Time.now.to_i + 10, "sub" => "subject"}, :exp, sub: "subject")
|
547
|
+
```
|
548
|
+
|
549
|
+
|
550
|
+
|
533
551
|
### Finding a Key
|
534
552
|
|
535
553
|
To dynamically find the key for verifying the JWT signature, pass a block to the decode block. The block receives headers and the original payload as parameters. It should return with the key to verify the signature that was used to sign the JWT.
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module Claims
|
5
|
+
# Context class to contain the data passed to individual claim validators
|
6
|
+
#
|
7
|
+
# @private
|
8
|
+
VerificationContext = Struct.new(:payload, keyword_init: true)
|
9
|
+
|
10
|
+
# Verifiers to support the ::JWT.decode method
|
11
|
+
#
|
12
|
+
# @private
|
13
|
+
module DecodeVerifier
|
14
|
+
VERIFIERS = {
|
15
|
+
verify_expiration: ->(options) { Claims::Expiration.new(leeway: options[:exp_leeway] || options[:leeway]) },
|
16
|
+
verify_not_before: ->(options) { Claims::NotBefore.new(leeway: options[:nbf_leeway] || options[:leeway]) },
|
17
|
+
verify_iss: ->(options) { options[:iss] && Claims::Issuer.new(issuers: options[:iss]) },
|
18
|
+
verify_iat: ->(*) { Claims::IssuedAt.new },
|
19
|
+
verify_jti: ->(options) { Claims::JwtId.new(validator: options[:verify_jti]) },
|
20
|
+
verify_aud: ->(options) { options[:aud] && Claims::Audience.new(expected_audience: options[:aud]) },
|
21
|
+
verify_sub: ->(options) { options[:sub] && Claims::Subject.new(expected_subject: options[:sub]) },
|
22
|
+
required_claims: ->(options) { Claims::Required.new(required_claims: options[:required_claims]) }
|
23
|
+
}.freeze
|
24
|
+
|
25
|
+
private_constant(:VERIFIERS)
|
26
|
+
|
27
|
+
class << self
|
28
|
+
# @private
|
29
|
+
def verify!(payload, options)
|
30
|
+
VERIFIERS.each do |key, verifier_builder|
|
31
|
+
next unless options[key] || options[key.to_s]
|
32
|
+
|
33
|
+
verifier_builder&.call(options)&.verify!(context: VerificationContext.new(payload: payload))
|
34
|
+
end
|
35
|
+
nil
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/jwt/claims/numeric.rb
CHANGED
@@ -3,10 +3,14 @@
|
|
3
3
|
module JWT
|
4
4
|
module Claims
|
5
5
|
class Numeric
|
6
|
-
|
7
|
-
|
6
|
+
class Compat
|
7
|
+
def initialize(payload)
|
8
|
+
@payload = payload
|
9
|
+
end
|
8
10
|
|
9
|
-
|
11
|
+
def verify!
|
12
|
+
JWT::Claims.verify_payload!(@payload, :numeric)
|
13
|
+
end
|
10
14
|
end
|
11
15
|
|
12
16
|
NUMERIC_CLAIMS = %i[
|
@@ -15,28 +19,36 @@ module JWT
|
|
15
19
|
nbf
|
16
20
|
].freeze
|
17
21
|
|
18
|
-
def
|
19
|
-
|
22
|
+
def self.new(*args)
|
23
|
+
return super if args.empty?
|
24
|
+
|
25
|
+
Compat.new(*args)
|
20
26
|
end
|
21
27
|
|
22
|
-
def verify!
|
23
|
-
validate_numeric_claims
|
28
|
+
def verify!(context:)
|
29
|
+
validate_numeric_claims(context.payload)
|
30
|
+
end
|
24
31
|
|
25
|
-
|
32
|
+
def self.verify!(payload:, **_args)
|
33
|
+
JWT::Claims.verify_payload!(payload, :numeric)
|
26
34
|
end
|
27
35
|
|
28
36
|
private
|
29
37
|
|
30
|
-
def validate_numeric_claims
|
38
|
+
def validate_numeric_claims(payload)
|
31
39
|
NUMERIC_CLAIMS.each do |claim|
|
32
|
-
validate_is_numeric(
|
40
|
+
validate_is_numeric(payload, claim)
|
33
41
|
end
|
34
42
|
end
|
35
43
|
|
36
|
-
def validate_is_numeric(claim)
|
37
|
-
return
|
44
|
+
def validate_is_numeric(payload, claim)
|
45
|
+
return unless payload.is_a?(Hash)
|
46
|
+
return unless payload.key?(claim) ||
|
47
|
+
payload.key?(claim.to_s)
|
48
|
+
|
49
|
+
return if payload[claim].is_a?(::Numeric) || payload[claim.to_s].is_a?(::Numeric)
|
38
50
|
|
39
|
-
raise InvalidPayload, "#{claim} claim must be a Numeric value but it is a #{
|
51
|
+
raise InvalidPayload, "#{claim} claim must be a Numeric value but it is a #{(payload[claim] || payload[claim.to_s]).class}"
|
40
52
|
end
|
41
53
|
end
|
42
54
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module Claims
|
5
|
+
# @private
|
6
|
+
module Verifier
|
7
|
+
VERIFIERS = {
|
8
|
+
exp: ->(options) { Claims::Expiration.new(leeway: options.dig(:exp, :leeway)) },
|
9
|
+
nbf: ->(options) { Claims::NotBefore.new(leeway: options.dig(:nbf, :leeway)) },
|
10
|
+
iss: ->(options) { Claims::Issuer.new(issuers: options[:iss]) },
|
11
|
+
iat: ->(*) { Claims::IssuedAt.new },
|
12
|
+
jti: ->(options) { Claims::JwtId.new(validator: options[:jti]) },
|
13
|
+
aud: ->(options) { Claims::Audience.new(expected_audience: options[:aud]) },
|
14
|
+
sub: ->(options) { Claims::Subject.new(expected_subject: options[:sub]) },
|
15
|
+
|
16
|
+
required: ->(options) { Claims::Required.new(required_claims: options[:required]) },
|
17
|
+
numeric: ->(*) { Claims::Numeric.new }
|
18
|
+
}.freeze
|
19
|
+
|
20
|
+
private_constant(:VERIFIERS)
|
21
|
+
|
22
|
+
class << self
|
23
|
+
# @private
|
24
|
+
def verify!(context, *options)
|
25
|
+
iterate_verifiers(*options) do |verifier, verifier_options|
|
26
|
+
verify_one!(context, verifier, verifier_options)
|
27
|
+
end
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
# @private
|
32
|
+
def errors(context, *options)
|
33
|
+
errors = []
|
34
|
+
iterate_verifiers(*options) do |verifier, verifier_options|
|
35
|
+
verify_one!(context, verifier, verifier_options)
|
36
|
+
rescue ::JWT::DecodeError => e
|
37
|
+
errors << Error.new(message: e.message)
|
38
|
+
end
|
39
|
+
errors
|
40
|
+
end
|
41
|
+
|
42
|
+
# @private
|
43
|
+
def iterate_verifiers(*options)
|
44
|
+
options.each do |element|
|
45
|
+
if element.is_a?(Hash)
|
46
|
+
element.each_key { |key| yield(key, element) }
|
47
|
+
else
|
48
|
+
yield(element, {})
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def verify_one!(context, verifier, options)
|
56
|
+
verifier_builder = VERIFIERS.fetch(verifier) { raise ArgumentError, "#{verifier} not a valid claim verifier" }
|
57
|
+
verifier_builder.call(options || {}).verify!(context: context)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
data/lib/jwt/claims.rb
CHANGED
@@ -9,29 +9,73 @@ require_relative 'claims/not_before'
|
|
9
9
|
require_relative 'claims/numeric'
|
10
10
|
require_relative 'claims/required'
|
11
11
|
require_relative 'claims/subject'
|
12
|
+
require_relative 'claims/decode_verifier'
|
13
|
+
require_relative 'claims/verifier'
|
12
14
|
|
13
15
|
module JWT
|
16
|
+
# JWT Claim verifications
|
17
|
+
# https://datatracker.ietf.org/doc/html/rfc7519#section-4
|
18
|
+
#
|
19
|
+
# Verification is supported for the following claims:
|
20
|
+
# exp
|
21
|
+
# nbf
|
22
|
+
# iss
|
23
|
+
# iat
|
24
|
+
# jti
|
25
|
+
# aud
|
26
|
+
# sub
|
27
|
+
# required
|
28
|
+
# numeric
|
29
|
+
#
|
14
30
|
module Claims
|
15
|
-
|
16
|
-
|
17
|
-
VERIFIERS = {
|
18
|
-
verify_expiration: ->(options) { Claims::Expiration.new(leeway: options[:exp_leeway] || options[:leeway]) },
|
19
|
-
verify_not_before: ->(options) { Claims::NotBefore.new(leeway: options[:nbf_leeway] || options[:leeway]) },
|
20
|
-
verify_iss: ->(options) { Claims::Issuer.new(issuers: options[:iss]) },
|
21
|
-
verify_iat: ->(*) { Claims::IssuedAt.new },
|
22
|
-
verify_jti: ->(options) { Claims::JwtId.new(validator: options[:verify_jti]) },
|
23
|
-
verify_aud: ->(options) { Claims::Audience.new(expected_audience: options[:aud]) },
|
24
|
-
verify_sub: ->(options) { options[:sub] && Claims::Subject.new(expected_subject: options[:sub]) },
|
25
|
-
required_claims: ->(options) { Claims::Required.new(required_claims: options[:required_claims]) }
|
26
|
-
}.freeze
|
31
|
+
# Represents a claim verification error
|
32
|
+
Error = Struct.new(:message, keyword_init: true)
|
27
33
|
|
28
34
|
class << self
|
35
|
+
# @deprecated Use {verify_payload!} instead. Will be removed in the next major version of ruby-jwt.
|
29
36
|
def verify!(payload, options)
|
30
|
-
|
31
|
-
|
37
|
+
DecodeVerifier.verify!(payload, options)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Checks if the claims in the JWT payload are valid.
|
41
|
+
# @example
|
42
|
+
#
|
43
|
+
# ::JWT::Claims.verify_payload!({"exp" => Time.now.to_i + 10}, :exp)
|
44
|
+
# ::JWT::Claims.verify_payload!({"exp" => Time.now.to_i - 10}, exp: { leeway: 11})
|
45
|
+
#
|
46
|
+
# @param payload [Hash] the JWT payload.
|
47
|
+
# @param options [Array] the options for verifying the claims.
|
48
|
+
# @return [void]
|
49
|
+
# @raise [JWT::DecodeError] if any claim is invalid.
|
50
|
+
def verify_payload!(payload, *options)
|
51
|
+
verify_token!(VerificationContext.new(payload: payload), *options)
|
52
|
+
end
|
53
|
+
|
54
|
+
# Checks if the claims in the JWT payload are valid.
|
55
|
+
#
|
56
|
+
# @param payload [Hash] the JWT payload.
|
57
|
+
# @param options [Array] the options for verifying the claims.
|
58
|
+
# @return [Boolean] true if the claims are valid, false otherwise
|
59
|
+
def valid_payload?(payload, *options)
|
60
|
+
payload_errors(payload, *options).empty?
|
61
|
+
end
|
62
|
+
|
63
|
+
# Returns the errors in the claims of the JWT token.
|
64
|
+
#
|
65
|
+
# @param options [Array] the options for verifying the claims.
|
66
|
+
# @return [Array<JWT::Claims::Error>] the errors in the claims of the JWT
|
67
|
+
def payload_errors(payload, *options)
|
68
|
+
token_errors(VerificationContext.new(payload: payload), *options)
|
69
|
+
end
|
70
|
+
|
71
|
+
private
|
72
|
+
|
73
|
+
def verify_token!(token, *options)
|
74
|
+
Verifier.verify!(token, *options)
|
75
|
+
end
|
32
76
|
|
33
|
-
|
34
|
-
|
77
|
+
def token_errors(token, *options)
|
78
|
+
Verifier.errors(token, *options)
|
35
79
|
end
|
36
80
|
end
|
37
81
|
end
|
data/lib/jwt/decode.rb
CHANGED
@@ -49,6 +49,7 @@ module JWT
|
|
49
49
|
|
50
50
|
def verify_algo
|
51
51
|
raise JWT::IncorrectAlgorithm, 'An algorithm must be specified' if allowed_algorithms.empty?
|
52
|
+
raise JWT::DecodeError, 'Token header not a JSON object' unless header.is_a?(Hash)
|
52
53
|
raise JWT::IncorrectAlgorithm, 'Token is missing alg header' unless alg_in_header
|
53
54
|
raise JWT::IncorrectAlgorithm, 'Expected a different algorithm' if allowed_and_valid_algorithms.empty?
|
54
55
|
end
|
@@ -111,7 +112,7 @@ module JWT
|
|
111
112
|
end
|
112
113
|
|
113
114
|
def verify_claims
|
114
|
-
Claims.verify!(payload, @options)
|
115
|
+
Claims::DecodeVerifier.verify!(payload, @options)
|
115
116
|
end
|
116
117
|
|
117
118
|
def validate_segment_count!
|
data/lib/jwt/encode.rb
CHANGED
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module JWA
|
5
|
+
module Compat
|
6
|
+
module ClassMethods
|
7
|
+
def from_algorithm(algorithm)
|
8
|
+
new(algorithm)
|
9
|
+
end
|
10
|
+
|
11
|
+
def sign(algorithm, msg, key)
|
12
|
+
Deprecations.warning('Support for calling sign with positional arguments will be removed in future ruby-jwt versions')
|
13
|
+
|
14
|
+
from_algorithm(algorithm).sign(data: msg, signing_key: key)
|
15
|
+
end
|
16
|
+
|
17
|
+
def verify(algorithm, key, signing_input, signature)
|
18
|
+
Deprecations.warning('Support for calling verify with positional arguments will be removed in future ruby-jwt versions')
|
19
|
+
|
20
|
+
from_algorithm(algorithm).verify(data: signing_input, signature: signature, verification_key: key)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.included(klass)
|
25
|
+
klass.extend(ClassMethods)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/jwt/jwa/ecdsa.rb
CHANGED
@@ -59,6 +59,10 @@ module JWT
|
|
59
59
|
register_algorithm(new(v[:algorithm], v[:digest]))
|
60
60
|
end
|
61
61
|
|
62
|
+
def self.from_algorithm(algorithm)
|
63
|
+
new(algorithm, algorithm.downcase.gsub('es', 'sha'))
|
64
|
+
end
|
65
|
+
|
62
66
|
def self.curve_by_name(name)
|
63
67
|
NAMED_CURVES.fetch(name) do
|
64
68
|
raise UnsupportedEcdsaCurve, "The ECDSA curve '#{name}' is not supported"
|
data/lib/jwt/jwa/hmac.rb
CHANGED
data/lib/jwt/jwa/hmac_rbnacl.rb
CHANGED
data/lib/jwt/jwa.rb
CHANGED
@@ -8,6 +8,7 @@ rescue LoadError
|
|
8
8
|
raise if defined?(RbNaCl)
|
9
9
|
end
|
10
10
|
|
11
|
+
require_relative 'jwa/compat'
|
11
12
|
require_relative 'jwa/signing_algorithm'
|
12
13
|
require_relative 'jwa/ecdsa'
|
13
14
|
require_relative 'jwa/hmac'
|
@@ -34,12 +35,16 @@ module JWT
|
|
34
35
|
return find(algorithm) if algorithm.is_a?(String) || algorithm.is_a?(Symbol)
|
35
36
|
|
36
37
|
unless algorithm.is_a?(SigningAlgorithm)
|
37
|
-
Deprecations.warning('Custom algorithms are required to include JWT::JWA::SigningAlgorithm')
|
38
|
+
Deprecations.warning('Custom algorithms are required to include JWT::JWA::SigningAlgorithm. Custom algorithms that do not include this module may stop working in the next major version of ruby-jwt.')
|
38
39
|
return Wrapper.new(algorithm)
|
39
40
|
end
|
40
41
|
|
41
42
|
algorithm
|
42
43
|
end
|
44
|
+
|
45
|
+
def create(algorithm)
|
46
|
+
resolve(algorithm)
|
47
|
+
end
|
43
48
|
end
|
44
49
|
end
|
45
50
|
end
|
data/lib/jwt/verify.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'error'
|
4
|
+
|
5
|
+
module JWT
|
6
|
+
class Verify
|
7
|
+
DEFAULTS = { leeway: 0 }.freeze
|
8
|
+
METHODS = %w[verify_aud verify_expiration verify_iat verify_iss verify_jti verify_not_before verify_sub verify_required_claims].freeze
|
9
|
+
|
10
|
+
class << self
|
11
|
+
METHODS.each do |method_name|
|
12
|
+
define_method(method_name) do |payload, options|
|
13
|
+
new(payload, options).send(method_name)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def verify_claims(payload, options)
|
18
|
+
::JWT::Claims.verify!(payload, options)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def initialize(payload, options)
|
23
|
+
@payload = payload
|
24
|
+
@options = DEFAULTS.merge(options)
|
25
|
+
end
|
26
|
+
|
27
|
+
METHODS.each do |method_name|
|
28
|
+
define_method(method_name) do
|
29
|
+
::JWT::Claims.verify!(@payload, @options.merge(method_name => true))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/jwt/version.rb
CHANGED
data/lib/jwt.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jwt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.9.
|
4
|
+
version: 2.9.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Rudat
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-10-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: base64
|
@@ -125,6 +125,7 @@ files:
|
|
125
125
|
- lib/jwt/base64.rb
|
126
126
|
- lib/jwt/claims.rb
|
127
127
|
- lib/jwt/claims/audience.rb
|
128
|
+
- lib/jwt/claims/decode_verifier.rb
|
128
129
|
- lib/jwt/claims/expiration.rb
|
129
130
|
- lib/jwt/claims/issued_at.rb
|
130
131
|
- lib/jwt/claims/issuer.rb
|
@@ -133,6 +134,8 @@ files:
|
|
133
134
|
- lib/jwt/claims/numeric.rb
|
134
135
|
- lib/jwt/claims/required.rb
|
135
136
|
- lib/jwt/claims/subject.rb
|
137
|
+
- lib/jwt/claims/verifier.rb
|
138
|
+
- lib/jwt/claims_validator.rb
|
136
139
|
- lib/jwt/configuration.rb
|
137
140
|
- lib/jwt/configuration/container.rb
|
138
141
|
- lib/jwt/configuration/decode_configuration.rb
|
@@ -143,6 +146,7 @@ files:
|
|
143
146
|
- lib/jwt/error.rb
|
144
147
|
- lib/jwt/json.rb
|
145
148
|
- lib/jwt/jwa.rb
|
149
|
+
- lib/jwt/jwa/compat.rb
|
146
150
|
- lib/jwt/jwa/ecdsa.rb
|
147
151
|
- lib/jwt/jwa/eddsa.rb
|
148
152
|
- lib/jwt/jwa/hmac.rb
|
@@ -164,6 +168,7 @@ files:
|
|
164
168
|
- lib/jwt/jwk/rsa.rb
|
165
169
|
- lib/jwt/jwk/set.rb
|
166
170
|
- lib/jwt/jwk/thumbprint.rb
|
171
|
+
- lib/jwt/verify.rb
|
167
172
|
- lib/jwt/version.rb
|
168
173
|
- lib/jwt/x5c_key_finder.rb
|
169
174
|
- ruby-jwt.gemspec
|
@@ -172,7 +177,7 @@ licenses:
|
|
172
177
|
- MIT
|
173
178
|
metadata:
|
174
179
|
bug_tracker_uri: https://github.com/jwt/ruby-jwt/issues
|
175
|
-
changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.9.
|
180
|
+
changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.9.2/CHANGELOG.md
|
176
181
|
rubygems_mfa_required: 'true'
|
177
182
|
post_install_message:
|
178
183
|
rdoc_options: []
|