jwt 2.4.1 → 2.9.3
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +177 -14
- data/CONTRIBUTING.md +7 -7
- data/README.md +180 -37
- data/lib/jwt/base64.rb +33 -0
- data/lib/jwt/claims/audience.rb +20 -0
- data/lib/jwt/claims/decode_verifier.rb +40 -0
- data/lib/jwt/claims/expiration.rb +22 -0
- data/lib/jwt/claims/issued_at.rb +15 -0
- data/lib/jwt/claims/issuer.rb +24 -0
- data/lib/jwt/claims/jwt_id.rb +25 -0
- data/lib/jwt/claims/not_before.rb +22 -0
- data/lib/jwt/claims/numeric.rb +55 -0
- data/lib/jwt/claims/required.rb +23 -0
- data/lib/jwt/claims/subject.rb +20 -0
- data/lib/jwt/claims/verifier.rb +62 -0
- data/lib/jwt/claims.rb +82 -0
- data/lib/jwt/claims_validator.rb +3 -24
- data/lib/jwt/configuration/container.rb +32 -0
- data/lib/jwt/configuration/decode_configuration.rb +46 -0
- data/lib/jwt/configuration/jwk_configuration.rb +27 -0
- data/lib/jwt/configuration.rb +15 -0
- data/lib/jwt/decode.rb +54 -41
- data/lib/jwt/deprecations.rb +48 -0
- data/lib/jwt/encode.rb +21 -21
- data/lib/jwt/error.rb +1 -0
- data/lib/jwt/jwa/compat.rb +29 -0
- data/lib/jwt/jwa/ecdsa.rb +93 -0
- data/lib/jwt/jwa/eddsa.rb +34 -0
- data/lib/jwt/jwa/hmac.rb +83 -0
- data/lib/jwt/jwa/hmac_rbnacl.rb +49 -0
- data/lib/jwt/jwa/hmac_rbnacl_fixed.rb +46 -0
- data/lib/jwt/jwa/none.rb +23 -0
- data/lib/jwt/jwa/ps.rb +36 -0
- data/lib/jwt/jwa/rsa.rb +36 -0
- data/lib/jwt/jwa/signing_algorithm.rb +60 -0
- data/lib/jwt/jwa/unsupported.rb +19 -0
- data/lib/jwt/jwa/wrapper.rb +43 -0
- data/lib/jwt/jwa.rb +50 -0
- data/lib/jwt/jwk/ec.rb +162 -65
- data/lib/jwt/jwk/hmac.rb +69 -24
- data/lib/jwt/jwk/key_base.rb +45 -7
- data/lib/jwt/jwk/key_finder.rb +19 -35
- data/lib/jwt/jwk/kid_as_key_digest.rb +15 -0
- data/lib/jwt/jwk/okp_rbnacl.rb +110 -0
- data/lib/jwt/jwk/rsa.rb +141 -54
- data/lib/jwt/jwk/set.rb +80 -0
- data/lib/jwt/jwk/thumbprint.rb +26 -0
- data/lib/jwt/jwk.rb +14 -11
- data/lib/jwt/verify.rb +10 -89
- data/lib/jwt/version.rb +24 -2
- data/lib/jwt/x5c_key_finder.rb +3 -6
- data/lib/jwt.rb +12 -4
- data/ruby-jwt.gemspec +11 -4
- metadata +59 -31
- data/.codeclimate.yml +0 -8
- data/.github/workflows/coverage.yml +0 -27
- data/.github/workflows/test.yml +0 -66
- data/.gitignore +0 -13
- data/.reek.yml +0 -22
- data/.rspec +0 -2
- data/.rubocop.yml +0 -67
- data/.sourcelevel.yml +0 -17
- data/Appraisals +0 -13
- data/Gemfile +0 -7
- data/Rakefile +0 -16
- data/lib/jwt/algos/ecdsa.rb +0 -64
- data/lib/jwt/algos/eddsa.rb +0 -33
- data/lib/jwt/algos/hmac.rb +0 -36
- data/lib/jwt/algos/none.rb +0 -17
- data/lib/jwt/algos/ps.rb +0 -43
- data/lib/jwt/algos/rsa.rb +0 -22
- data/lib/jwt/algos/unsupported.rb +0 -19
- data/lib/jwt/algos.rb +0 -44
- data/lib/jwt/default_options.rb +0 -18
- data/lib/jwt/security_utils.rb +0 -59
- data/lib/jwt/signature.rb +0 -35
@@ -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
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module Claims
|
5
|
+
class Expiration
|
6
|
+
def initialize(leeway:)
|
7
|
+
@leeway = leeway || 0
|
8
|
+
end
|
9
|
+
|
10
|
+
def verify!(context:, **_args)
|
11
|
+
return unless context.payload.is_a?(Hash)
|
12
|
+
return unless context.payload.key?('exp')
|
13
|
+
|
14
|
+
raise JWT::ExpiredSignature, 'Signature has expired' if context.payload['exp'].to_i <= (Time.now.to_i - leeway)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :leeway
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module Claims
|
5
|
+
class IssuedAt
|
6
|
+
def verify!(context:, **_args)
|
7
|
+
return unless context.payload.is_a?(Hash)
|
8
|
+
return unless context.payload.key?('iat')
|
9
|
+
|
10
|
+
iat = context.payload['iat']
|
11
|
+
raise(JWT::InvalidIatError, 'Invalid iat') if !iat.is_a?(::Numeric) || iat.to_f > Time.now.to_f
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module Claims
|
5
|
+
class Issuer
|
6
|
+
def initialize(issuers:)
|
7
|
+
@issuers = Array(issuers).map { |item| item.is_a?(Symbol) ? item.to_s : item }
|
8
|
+
end
|
9
|
+
|
10
|
+
def verify!(context:, **_args)
|
11
|
+
case (iss = context.payload['iss'])
|
12
|
+
when *issuers
|
13
|
+
nil
|
14
|
+
else
|
15
|
+
raise JWT::InvalidIssuerError, "Invalid issuer. Expected #{issuers}, received #{iss || '<none>'}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
attr_reader :issuers
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module Claims
|
5
|
+
class JwtId
|
6
|
+
def initialize(validator:)
|
7
|
+
@validator = validator
|
8
|
+
end
|
9
|
+
|
10
|
+
def verify!(context:, **_args)
|
11
|
+
jti = context.payload['jti']
|
12
|
+
if validator.respond_to?(:call)
|
13
|
+
verified = validator.arity == 2 ? validator.call(jti, context.payload) : validator.call(jti)
|
14
|
+
raise(JWT::InvalidJtiError, 'Invalid jti') unless verified
|
15
|
+
elsif jti.to_s.strip.empty?
|
16
|
+
raise(JWT::InvalidJtiError, 'Missing jti')
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :validator
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module Claims
|
5
|
+
class NotBefore
|
6
|
+
def initialize(leeway:)
|
7
|
+
@leeway = leeway || 0
|
8
|
+
end
|
9
|
+
|
10
|
+
def verify!(context:, **_args)
|
11
|
+
return unless context.payload.is_a?(Hash)
|
12
|
+
return unless context.payload.key?('nbf')
|
13
|
+
|
14
|
+
raise JWT::ImmatureSignature, 'Signature nbf has not been reached' if context.payload['nbf'].to_i > (Time.now.to_i + leeway)
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
attr_reader :leeway
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module Claims
|
5
|
+
class Numeric
|
6
|
+
class Compat
|
7
|
+
def initialize(payload)
|
8
|
+
@payload = payload
|
9
|
+
end
|
10
|
+
|
11
|
+
def verify!
|
12
|
+
JWT::Claims.verify_payload!(@payload, :numeric)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
NUMERIC_CLAIMS = %i[
|
17
|
+
exp
|
18
|
+
iat
|
19
|
+
nbf
|
20
|
+
].freeze
|
21
|
+
|
22
|
+
def self.new(*args)
|
23
|
+
return super if args.empty?
|
24
|
+
|
25
|
+
Compat.new(*args)
|
26
|
+
end
|
27
|
+
|
28
|
+
def verify!(context:)
|
29
|
+
validate_numeric_claims(context.payload)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.verify!(payload:, **_args)
|
33
|
+
JWT::Claims.verify_payload!(payload, :numeric)
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def validate_numeric_claims(payload)
|
39
|
+
NUMERIC_CLAIMS.each do |claim|
|
40
|
+
validate_is_numeric(payload, claim)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
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)
|
50
|
+
|
51
|
+
raise InvalidPayload, "#{claim} claim must be a Numeric value but it is a #{(payload[claim] || payload[claim.to_s]).class}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module Claims
|
5
|
+
class Required
|
6
|
+
def initialize(required_claims:)
|
7
|
+
@required_claims = required_claims
|
8
|
+
end
|
9
|
+
|
10
|
+
def verify!(context:, **_args)
|
11
|
+
required_claims.each do |required_claim|
|
12
|
+
next if context.payload.is_a?(Hash) && context.payload.key?(required_claim)
|
13
|
+
|
14
|
+
raise JWT::MissingRequiredClaim, "Missing required claim #{required_claim}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :required_claims
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module Claims
|
5
|
+
class Subject
|
6
|
+
def initialize(expected_subject:)
|
7
|
+
@expected_subject = expected_subject.to_s
|
8
|
+
end
|
9
|
+
|
10
|
+
def verify!(context:, **_args)
|
11
|
+
sub = context.payload['sub']
|
12
|
+
raise(JWT::InvalidSubError, "Invalid subject. Expected #{expected_subject}, received #{sub || '<none>'}") unless sub.to_s == expected_subject
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
attr_reader :expected_subject
|
18
|
+
end
|
19
|
+
end
|
20
|
+
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
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'claims/audience'
|
4
|
+
require_relative 'claims/expiration'
|
5
|
+
require_relative 'claims/issued_at'
|
6
|
+
require_relative 'claims/issuer'
|
7
|
+
require_relative 'claims/jwt_id'
|
8
|
+
require_relative 'claims/not_before'
|
9
|
+
require_relative 'claims/numeric'
|
10
|
+
require_relative 'claims/required'
|
11
|
+
require_relative 'claims/subject'
|
12
|
+
require_relative 'claims/decode_verifier'
|
13
|
+
require_relative 'claims/verifier'
|
14
|
+
|
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
|
+
#
|
30
|
+
module Claims
|
31
|
+
# Represents a claim verification error
|
32
|
+
Error = Struct.new(:message, keyword_init: true)
|
33
|
+
|
34
|
+
class << self
|
35
|
+
# @deprecated Use {verify_payload!} instead. Will be removed in the next major version of ruby-jwt.
|
36
|
+
def verify!(payload, options)
|
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
|
76
|
+
|
77
|
+
def token_errors(token, *options)
|
78
|
+
Verifier.errors(token, *options)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
data/lib/jwt/claims_validator.rb
CHANGED
@@ -1,37 +1,16 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require_relative '
|
3
|
+
require_relative 'error'
|
4
4
|
|
5
5
|
module JWT
|
6
6
|
class ClaimsValidator
|
7
|
-
NUMERIC_CLAIMS = %i[
|
8
|
-
exp
|
9
|
-
iat
|
10
|
-
nbf
|
11
|
-
].freeze
|
12
|
-
|
13
7
|
def initialize(payload)
|
14
|
-
@payload = payload
|
8
|
+
@payload = payload
|
15
9
|
end
|
16
10
|
|
17
11
|
def validate!
|
18
|
-
|
19
|
-
|
12
|
+
Claims.verify_payload!(@payload, :numeric)
|
20
13
|
true
|
21
14
|
end
|
22
|
-
|
23
|
-
private
|
24
|
-
|
25
|
-
def validate_numeric_claims
|
26
|
-
NUMERIC_CLAIMS.each do |claim|
|
27
|
-
validate_is_numeric(claim) if @payload.key?(claim)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
def validate_is_numeric(claim)
|
32
|
-
return if @payload[claim].is_a?(Numeric)
|
33
|
-
|
34
|
-
raise InvalidPayload, "#{claim} claim must be a Numeric value but it is a #{@payload[claim].class}"
|
35
|
-
end
|
36
15
|
end
|
37
16
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'decode_configuration'
|
4
|
+
require_relative 'jwk_configuration'
|
5
|
+
|
6
|
+
module JWT
|
7
|
+
module Configuration
|
8
|
+
class Container
|
9
|
+
attr_accessor :decode, :jwk, :strict_base64_decoding
|
10
|
+
attr_reader :deprecation_warnings
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
reset!
|
14
|
+
end
|
15
|
+
|
16
|
+
def reset!
|
17
|
+
@decode = DecodeConfiguration.new
|
18
|
+
@jwk = JwkConfiguration.new
|
19
|
+
@strict_base64_decoding = false
|
20
|
+
|
21
|
+
self.deprecation_warnings = :once
|
22
|
+
end
|
23
|
+
|
24
|
+
DEPRECATION_WARNINGS_VALUES = %i[once warn silent].freeze
|
25
|
+
def deprecation_warnings=(value)
|
26
|
+
raise ArgumentError, "Invalid deprecation_warnings value #{value}. Supported values: #{DEPRECATION_WARNINGS_VALUES}" unless DEPRECATION_WARNINGS_VALUES.include?(value)
|
27
|
+
|
28
|
+
@deprecation_warnings = value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
module Configuration
|
5
|
+
class DecodeConfiguration
|
6
|
+
attr_accessor :verify_expiration,
|
7
|
+
:verify_not_before,
|
8
|
+
:verify_iss,
|
9
|
+
:verify_iat,
|
10
|
+
:verify_jti,
|
11
|
+
:verify_aud,
|
12
|
+
:verify_sub,
|
13
|
+
:leeway,
|
14
|
+
:algorithms,
|
15
|
+
:required_claims
|
16
|
+
|
17
|
+
def initialize
|
18
|
+
@verify_expiration = true
|
19
|
+
@verify_not_before = true
|
20
|
+
@verify_iss = false
|
21
|
+
@verify_iat = false
|
22
|
+
@verify_jti = false
|
23
|
+
@verify_aud = false
|
24
|
+
@verify_sub = false
|
25
|
+
@leeway = 0
|
26
|
+
@algorithms = ['HS256']
|
27
|
+
@required_claims = []
|
28
|
+
end
|
29
|
+
|
30
|
+
def to_h
|
31
|
+
{
|
32
|
+
verify_expiration: verify_expiration,
|
33
|
+
verify_not_before: verify_not_before,
|
34
|
+
verify_iss: verify_iss,
|
35
|
+
verify_iat: verify_iat,
|
36
|
+
verify_jti: verify_jti,
|
37
|
+
verify_aud: verify_aud,
|
38
|
+
verify_sub: verify_sub,
|
39
|
+
leeway: leeway,
|
40
|
+
algorithms: algorithms,
|
41
|
+
required_claims: required_claims
|
42
|
+
}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../jwk/kid_as_key_digest'
|
4
|
+
require_relative '../jwk/thumbprint'
|
5
|
+
|
6
|
+
module JWT
|
7
|
+
module Configuration
|
8
|
+
class JwkConfiguration
|
9
|
+
def initialize
|
10
|
+
self.kid_generator_type = :key_digest
|
11
|
+
end
|
12
|
+
|
13
|
+
def kid_generator_type=(value)
|
14
|
+
self.kid_generator = case value
|
15
|
+
when :key_digest
|
16
|
+
JWT::JWK::KidAsKeyDigest
|
17
|
+
when :rfc7638_thumbprint
|
18
|
+
JWT::JWK::Thumbprint
|
19
|
+
else
|
20
|
+
raise ArgumentError, "#{value} is not a valid kid generator type."
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_accessor :kid_generator
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'configuration/container'
|
4
|
+
|
5
|
+
module JWT
|
6
|
+
module Configuration
|
7
|
+
def configure
|
8
|
+
yield(configuration)
|
9
|
+
end
|
10
|
+
|
11
|
+
def configuration
|
12
|
+
@configuration ||= ::JWT::Configuration::Container.new
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|