jwt 2.9.2 → 2.10.0
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 +21 -16
- data/README.md +153 -83
- data/lib/jwt/base64.rb +3 -0
- data/lib/jwt/claims/audience.rb +10 -0
- data/lib/jwt/claims/crit.rb +35 -0
- data/lib/jwt/claims/decode_verifier.rb +3 -3
- data/lib/jwt/claims/expiration.rb +10 -0
- data/lib/jwt/claims/issued_at.rb +7 -0
- data/lib/jwt/claims/issuer.rb +10 -0
- data/lib/jwt/claims/jwt_id.rb +10 -0
- data/lib/jwt/claims/not_before.rb +10 -0
- data/lib/jwt/claims/numeric.rb +22 -0
- data/lib/jwt/claims/required.rb +10 -0
- data/lib/jwt/claims/subject.rb +10 -0
- data/lib/jwt/claims/verification_methods.rb +20 -0
- data/lib/jwt/claims/verifier.rb +6 -7
- data/lib/jwt/claims.rb +6 -14
- data/lib/jwt/claims_validator.rb +5 -2
- data/lib/jwt/configuration/container.rb +20 -0
- data/lib/jwt/configuration/decode_configuration.rb +24 -0
- data/lib/jwt/configuration/jwk_configuration.rb +1 -0
- data/lib/jwt/configuration.rb +8 -0
- data/lib/jwt/decode.rb +28 -68
- data/lib/jwt/deprecations.rb +1 -0
- data/lib/jwt/encode.rb +17 -56
- data/lib/jwt/encoded_token.rb +139 -0
- data/lib/jwt/error.rb +34 -0
- data/lib/jwt/json.rb +1 -1
- data/lib/jwt/jwa/compat.rb +3 -0
- data/lib/jwt/jwa/ecdsa.rb +3 -6
- data/lib/jwt/jwa/eddsa.rb +7 -6
- data/lib/jwt/jwa/hmac.rb +2 -3
- data/lib/jwt/jwa/hmac_rbnacl.rb +1 -0
- data/lib/jwt/jwa/hmac_rbnacl_fixed.rb +1 -0
- data/lib/jwt/jwa/none.rb +1 -0
- data/lib/jwt/jwa/ps.rb +2 -3
- data/lib/jwt/jwa/rsa.rb +2 -3
- data/lib/jwt/jwa/signing_algorithm.rb +3 -0
- data/lib/jwt/jwa/unsupported.rb +1 -0
- data/lib/jwt/jwa/wrapper.rb +1 -0
- data/lib/jwt/jwa.rb +11 -3
- data/lib/jwt/jwk/ec.rb +2 -3
- data/lib/jwt/jwk/hmac.rb +2 -3
- data/lib/jwt/jwk/key_base.rb +1 -0
- data/lib/jwt/jwk/key_finder.rb +1 -0
- data/lib/jwt/jwk/kid_as_key_digest.rb +1 -0
- data/lib/jwt/jwk/okp_rbnacl.rb +3 -4
- data/lib/jwt/jwk/rsa.rb +2 -3
- data/lib/jwt/jwk/set.rb +2 -0
- data/lib/jwt/jwk.rb +1 -0
- data/lib/jwt/token.rb +112 -0
- data/lib/jwt/verify.rb +7 -0
- data/lib/jwt/version.rb +33 -10
- data/lib/jwt.rb +16 -0
- metadata +8 -4
data/lib/jwt/token.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
# Represents a JWT token
|
5
|
+
#
|
6
|
+
# Basic token signed using the HS256 algorithm:
|
7
|
+
#
|
8
|
+
# token = JWT::Token.new(payload: {pay: 'load'})
|
9
|
+
# token.sign!(algorithm: 'HS256', key: 'secret')
|
10
|
+
# token.jwt # => eyJhb....
|
11
|
+
#
|
12
|
+
# Custom headers will be combined with generated headers:
|
13
|
+
# token = JWT::Token.new(payload: {pay: 'load'}, header: {custom: "value"})
|
14
|
+
# token.sign!(algorithm: 'HS256', key: 'secret')
|
15
|
+
# token.header # => {"custom"=>"value", "alg"=>"HS256"}
|
16
|
+
#
|
17
|
+
class Token
|
18
|
+
include Claims::VerificationMethods
|
19
|
+
|
20
|
+
# Initializes a new Token instance.
|
21
|
+
#
|
22
|
+
# @param header [Hash] the header of the JWT token.
|
23
|
+
# @param payload [Hash] the payload of the JWT token.
|
24
|
+
def initialize(payload:, header: {})
|
25
|
+
@header = header&.transform_keys(&:to_s)
|
26
|
+
@payload = payload
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns the decoded signature of the JWT token.
|
30
|
+
#
|
31
|
+
# @return [String] the decoded signature of the JWT token.
|
32
|
+
def signature
|
33
|
+
@signature ||= ::JWT::Base64.url_decode(encoded_signature || '')
|
34
|
+
end
|
35
|
+
|
36
|
+
# Returns the encoded signature of the JWT token.
|
37
|
+
#
|
38
|
+
# @return [String] the encoded signature of the JWT token.
|
39
|
+
def encoded_signature
|
40
|
+
@encoded_signature ||= ::JWT::Base64.url_encode(signature)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns the decoded header of the JWT token.
|
44
|
+
#
|
45
|
+
# @return [Hash] the header of the JWT token.
|
46
|
+
attr_reader :header
|
47
|
+
|
48
|
+
# Returns the encoded header of the JWT token.
|
49
|
+
#
|
50
|
+
# @return [String] the encoded header of the JWT token.
|
51
|
+
def encoded_header
|
52
|
+
@encoded_header ||= ::JWT::Base64.url_encode(JWT::JSON.generate(header))
|
53
|
+
end
|
54
|
+
|
55
|
+
# Returns the payload of the JWT token.
|
56
|
+
#
|
57
|
+
# @return [Hash] the payload of the JWT token.
|
58
|
+
attr_reader :payload
|
59
|
+
|
60
|
+
# Returns the encoded payload of the JWT token.
|
61
|
+
#
|
62
|
+
# @return [String] the encoded payload of the JWT token.
|
63
|
+
def encoded_payload
|
64
|
+
@encoded_payload ||= ::JWT::Base64.url_encode(JWT::JSON.generate(payload))
|
65
|
+
end
|
66
|
+
|
67
|
+
# Returns the signing input of the JWT token.
|
68
|
+
#
|
69
|
+
# @return [String] the signing input of the JWT token.
|
70
|
+
def signing_input
|
71
|
+
@signing_input ||= [encoded_header, encoded_payload].join('.')
|
72
|
+
end
|
73
|
+
|
74
|
+
# Returns the JWT token as a string.
|
75
|
+
#
|
76
|
+
# @return [String] the JWT token as a string.
|
77
|
+
# @raise [JWT::EncodeError] if the token is not signed or other encoding issues
|
78
|
+
def jwt
|
79
|
+
@jwt ||= (@signature && [encoded_header, @detached_payload ? '' : encoded_payload, encoded_signature].join('.')) || raise(::JWT::EncodeError, 'Token is not signed')
|
80
|
+
end
|
81
|
+
|
82
|
+
# Detaches the payload according to https://datatracker.ietf.org/doc/html/rfc7515#appendix-F
|
83
|
+
#
|
84
|
+
def detach_payload!
|
85
|
+
@detached_payload = true
|
86
|
+
|
87
|
+
nil
|
88
|
+
end
|
89
|
+
|
90
|
+
# Signs the JWT token.
|
91
|
+
#
|
92
|
+
# @param algorithm [String, Object] the algorithm to use for signing.
|
93
|
+
# @param key [String] the key to use for signing.
|
94
|
+
# @return [void]
|
95
|
+
# @raise [JWT::EncodeError] if the token is already signed or other problems when signing
|
96
|
+
def sign!(algorithm:, key:)
|
97
|
+
raise ::JWT::EncodeError, 'Token already signed' if @signature
|
98
|
+
|
99
|
+
JWA.resolve(algorithm).tap do |algo|
|
100
|
+
header.merge!(algo.header)
|
101
|
+
@signature = algo.sign(data: signing_input, signing_key: key)
|
102
|
+
end
|
103
|
+
|
104
|
+
nil
|
105
|
+
end
|
106
|
+
|
107
|
+
# Returns the JWT token as a string.
|
108
|
+
#
|
109
|
+
# @return [String] the JWT token as a string.
|
110
|
+
alias to_s jwt
|
111
|
+
end
|
112
|
+
end
|
data/lib/jwt/verify.rb
CHANGED
@@ -3,10 +3,12 @@
|
|
3
3
|
require_relative 'error'
|
4
4
|
|
5
5
|
module JWT
|
6
|
+
# @deprecated This class is deprecated and will be removed in the next major version of ruby-jwt.
|
6
7
|
class Verify
|
7
8
|
DEFAULTS = { leeway: 0 }.freeze
|
8
9
|
METHODS = %w[verify_aud verify_expiration verify_iat verify_iss verify_jti verify_not_before verify_sub verify_required_claims].freeze
|
9
10
|
|
11
|
+
private_constant(:DEFAULTS, :METHODS)
|
10
12
|
class << self
|
11
13
|
METHODS.each do |method_name|
|
12
14
|
define_method(method_name) do |payload, options|
|
@@ -14,12 +16,17 @@ module JWT
|
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
19
|
+
# @deprecated This method is deprecated and will be removed in the next major version of ruby-jwt.
|
17
20
|
def verify_claims(payload, options)
|
21
|
+
Deprecations.warning('The ::JWT::Verify.verify_claims method is deprecated and will be removed in the next major version of ruby-jwt')
|
18
22
|
::JWT::Claims.verify!(payload, options)
|
23
|
+
true
|
19
24
|
end
|
20
25
|
end
|
21
26
|
|
27
|
+
# @deprecated This class is deprecated and will be removed in the next major version of ruby-jwt.
|
22
28
|
def initialize(payload, options)
|
29
|
+
Deprecations.warning('The ::JWT::Verify class is deprecated and will be removed in the next major version of ruby-jwt')
|
23
30
|
@payload = payload
|
24
31
|
@options = DEFAULTS.merge(options)
|
25
32
|
end
|
data/lib/jwt/version.rb
CHANGED
@@ -1,44 +1,67 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
#
|
3
|
+
# JSON Web Token implementation
|
4
|
+
#
|
5
|
+
# Should be up to date with the latest spec:
|
6
|
+
# https://tools.ietf.org/html/rfc7519
|
4
7
|
module JWT
|
8
|
+
# Returns the gem version of the JWT library.
|
9
|
+
#
|
10
|
+
# @return [Gem::Version] the gem version.
|
5
11
|
def self.gem_version
|
6
|
-
Gem::Version.new
|
12
|
+
Gem::Version.new(VERSION::STRING)
|
7
13
|
end
|
8
14
|
|
9
|
-
#
|
15
|
+
# @api private
|
10
16
|
module VERSION
|
11
|
-
# major version
|
12
17
|
MAJOR = 2
|
13
|
-
|
14
|
-
|
15
|
-
# tiny version
|
16
|
-
TINY = 2
|
17
|
-
# alpha, beta, etc. tag
|
18
|
+
MINOR = 10
|
19
|
+
TINY = 0
|
18
20
|
PRE = nil
|
19
21
|
|
20
|
-
# Build version string
|
21
22
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
23
|
+
|
24
|
+
private_constant(:MAJOR, :MINOR, :TINY, :PRE)
|
22
25
|
end
|
23
26
|
|
27
|
+
# Checks if the OpenSSL version is 3 or greater.
|
28
|
+
#
|
29
|
+
# @return [Boolean] true if OpenSSL version is 3 or greater, false otherwise.
|
30
|
+
# @api private
|
24
31
|
def self.openssl_3?
|
25
32
|
return false if OpenSSL::OPENSSL_VERSION.include?('LibreSSL')
|
26
33
|
|
27
34
|
true if 3 * 0x10000000 <= OpenSSL::OPENSSL_VERSION_NUMBER
|
28
35
|
end
|
29
36
|
|
37
|
+
# Checks if the RbNaCl library is defined.
|
38
|
+
#
|
39
|
+
# @return [Boolean] true if RbNaCl is defined, false otherwise.
|
40
|
+
# @api private
|
30
41
|
def self.rbnacl?
|
31
42
|
defined?(::RbNaCl)
|
32
43
|
end
|
33
44
|
|
45
|
+
# Checks if the RbNaCl library version is 6.0.0 or greater.
|
46
|
+
#
|
47
|
+
# @return [Boolean] true if RbNaCl version is 6.0.0 or greater, false otherwise.
|
48
|
+
# @api private
|
34
49
|
def self.rbnacl_6_or_greater?
|
35
50
|
rbnacl? && ::Gem::Version.new(::RbNaCl::VERSION) >= ::Gem::Version.new('6.0.0')
|
36
51
|
end
|
37
52
|
|
53
|
+
# Checks if there is an OpenSSL 3 HMAC empty key regression.
|
54
|
+
#
|
55
|
+
# @return [Boolean] true if there is an OpenSSL 3 HMAC empty key regression, false otherwise.
|
56
|
+
# @api private
|
38
57
|
def self.openssl_3_hmac_empty_key_regression?
|
39
58
|
openssl_3? && openssl_version <= ::Gem::Version.new('3.0.0')
|
40
59
|
end
|
41
60
|
|
61
|
+
# Returns the OpenSSL version.
|
62
|
+
#
|
63
|
+
# @return [Gem::Version] the OpenSSL version.
|
64
|
+
# @api private
|
42
65
|
def self.openssl_version
|
43
66
|
@openssl_version ||= ::Gem::Version.new(OpenSSL::VERSION)
|
44
67
|
end
|
data/lib/jwt.rb
CHANGED
@@ -10,6 +10,8 @@ require 'jwt/encode'
|
|
10
10
|
require 'jwt/error'
|
11
11
|
require 'jwt/jwk'
|
12
12
|
require 'jwt/claims'
|
13
|
+
require 'jwt/encoded_token'
|
14
|
+
require 'jwt/token'
|
13
15
|
|
14
16
|
require 'jwt/claims_validator'
|
15
17
|
require 'jwt/verify'
|
@@ -23,6 +25,13 @@ module JWT
|
|
23
25
|
|
24
26
|
module_function
|
25
27
|
|
28
|
+
# Encodes a payload into a JWT.
|
29
|
+
#
|
30
|
+
# @param payload [Hash] the payload to encode.
|
31
|
+
# @param key [String] the key used to sign the JWT.
|
32
|
+
# @param algorithm [String] the algorithm used to sign the JWT.
|
33
|
+
# @param header_fields [Hash] additional headers to include in the JWT.
|
34
|
+
# @return [String] the encoded JWT.
|
26
35
|
def encode(payload, key, algorithm = 'HS256', header_fields = {})
|
27
36
|
Encode.new(payload: payload,
|
28
37
|
key: key,
|
@@ -30,6 +39,13 @@ module JWT
|
|
30
39
|
headers: header_fields).segments
|
31
40
|
end
|
32
41
|
|
42
|
+
# Decodes a JWT to extract the payload and header
|
43
|
+
#
|
44
|
+
# @param jwt [String] the JWT to decode.
|
45
|
+
# @param key [String] the key used to verify the JWT.
|
46
|
+
# @param verify [Boolean] whether to verify the JWT signature.
|
47
|
+
# @param options [Hash] additional options for decoding.
|
48
|
+
# @return [Array<Hash>] the decoded payload and headers.
|
33
49
|
def decode(jwt, key = nil, verify = true, options = {}, &keyfinder) # rubocop:disable Style/OptionalBooleanParameter
|
34
50
|
Deprecations.context do
|
35
51
|
Decode.new(jwt, key, verify, configuration.decode.to_h.merge(options), &keyfinder).decode_segments
|
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.
|
4
|
+
version: 2.10.0
|
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-12-25 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/crit.rb
|
128
129
|
- lib/jwt/claims/decode_verifier.rb
|
129
130
|
- lib/jwt/claims/expiration.rb
|
130
131
|
- lib/jwt/claims/issued_at.rb
|
@@ -134,6 +135,7 @@ files:
|
|
134
135
|
- lib/jwt/claims/numeric.rb
|
135
136
|
- lib/jwt/claims/required.rb
|
136
137
|
- lib/jwt/claims/subject.rb
|
138
|
+
- lib/jwt/claims/verification_methods.rb
|
137
139
|
- lib/jwt/claims/verifier.rb
|
138
140
|
- lib/jwt/claims_validator.rb
|
139
141
|
- lib/jwt/configuration.rb
|
@@ -143,6 +145,7 @@ files:
|
|
143
145
|
- lib/jwt/decode.rb
|
144
146
|
- lib/jwt/deprecations.rb
|
145
147
|
- lib/jwt/encode.rb
|
148
|
+
- lib/jwt/encoded_token.rb
|
146
149
|
- lib/jwt/error.rb
|
147
150
|
- lib/jwt/json.rb
|
148
151
|
- lib/jwt/jwa.rb
|
@@ -168,6 +171,7 @@ files:
|
|
168
171
|
- lib/jwt/jwk/rsa.rb
|
169
172
|
- lib/jwt/jwk/set.rb
|
170
173
|
- lib/jwt/jwk/thumbprint.rb
|
174
|
+
- lib/jwt/token.rb
|
171
175
|
- lib/jwt/verify.rb
|
172
176
|
- lib/jwt/version.rb
|
173
177
|
- lib/jwt/x5c_key_finder.rb
|
@@ -177,7 +181,7 @@ licenses:
|
|
177
181
|
- MIT
|
178
182
|
metadata:
|
179
183
|
bug_tracker_uri: https://github.com/jwt/ruby-jwt/issues
|
180
|
-
changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.
|
184
|
+
changelog_uri: https://github.com/jwt/ruby-jwt/blob/v2.10.0/CHANGELOG.md
|
181
185
|
rubygems_mfa_required: 'true'
|
182
186
|
post_install_message:
|
183
187
|
rdoc_options: []
|
@@ -194,7 +198,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
194
198
|
- !ruby/object:Gem::Version
|
195
199
|
version: '0'
|
196
200
|
requirements: []
|
197
|
-
rubygems_version: 3.5.
|
201
|
+
rubygems_version: 3.5.22
|
198
202
|
signing_key:
|
199
203
|
specification_version: 4
|
200
204
|
summary: JSON Web Token implementation in Ruby
|