jwt 1.5.2 → 1.5.4
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 +13 -5
- data/.codeclimate.yml +20 -0
- data/.gitignore +6 -0
- data/.rspec +2 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +13 -0
- data/Gemfile +4 -0
- data/README.md +29 -11
- data/Rakefile +1 -18
- data/lib/jwt.rb +19 -75
- data/lib/jwt/decode.rb +56 -0
- data/lib/jwt/error.rb +12 -0
- data/lib/jwt/json.rb +9 -25
- data/lib/jwt/verify.rb +98 -0
- data/lib/jwt/version.rb +23 -0
- data/ruby-jwt.gemspec +29 -0
- data/spec/fixtures/certs/ec256-private.pem +8 -0
- data/spec/fixtures/certs/ec256-public.pem +4 -0
- data/spec/fixtures/certs/ec256-wrong-private.pem +8 -0
- data/spec/fixtures/certs/ec256-wrong-public.pem +4 -0
- data/spec/fixtures/certs/ec384-private.pem +9 -0
- data/spec/fixtures/certs/ec384-public.pem +5 -0
- data/spec/fixtures/certs/ec384-wrong-private.pem +9 -0
- data/spec/fixtures/certs/ec384-wrong-public.pem +5 -0
- data/spec/fixtures/certs/ec512-private.pem +10 -0
- data/spec/fixtures/certs/ec512-public.pem +6 -0
- data/spec/fixtures/certs/ec512-wrong-private.pem +10 -0
- data/spec/fixtures/certs/ec512-wrong-public.pem +6 -0
- data/spec/fixtures/certs/rsa-1024-private.pem +15 -0
- data/spec/fixtures/certs/rsa-1024-public.pem +6 -0
- data/spec/fixtures/certs/rsa-2048-private.pem +27 -0
- data/spec/fixtures/certs/rsa-2048-public.pem +9 -0
- data/spec/fixtures/certs/rsa-2048-wrong-private.pem +27 -0
- data/spec/fixtures/certs/rsa-2048-wrong-public.pem +9 -0
- data/spec/fixtures/certs/rsa-4096-private.pem +51 -0
- data/spec/fixtures/certs/rsa-4096-public.pem +14 -0
- data/spec/jwt/verify_spec.rb +175 -0
- data/spec/jwt_spec.rb +1 -181
- data/spec/spec_helper.rb +2 -3
- metadata +145 -28
- data/jwt.gemspec +0 -34
data/lib/jwt/verify.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'jwt/error'
|
2
|
+
|
3
|
+
module JWT
|
4
|
+
# JWT verify methods
|
5
|
+
class Verify
|
6
|
+
class << self
|
7
|
+
%w[verify_aud verify_expiration verify_iat verify_iss verify_jti verify_not_before verify_sub].each do |method_name|
|
8
|
+
define_method method_name do |payload, options|
|
9
|
+
new(payload, options).send(method_name)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(payload, options)
|
15
|
+
@payload = payload
|
16
|
+
@options = options
|
17
|
+
end
|
18
|
+
|
19
|
+
def verify_aud
|
20
|
+
return unless (options_aud = extract_option(:aud))
|
21
|
+
|
22
|
+
if @payload['aud'].is_a?(Array)
|
23
|
+
fail(
|
24
|
+
JWT::InvalidAudError,
|
25
|
+
'Invalid audience'
|
26
|
+
) unless @payload['aud'].include?(options_aud.to_s)
|
27
|
+
else
|
28
|
+
fail(
|
29
|
+
JWT::InvalidAudError,
|
30
|
+
"Invalid audience. Expected #{options_aud}, received #{@payload['aud'] || '<none>'}"
|
31
|
+
) unless @payload['aud'].to_s == options_aud.to_s
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def verify_expiration
|
36
|
+
return unless @payload.include?('exp')
|
37
|
+
|
38
|
+
if @payload['exp'].to_i < (Time.now.to_i - leeway)
|
39
|
+
fail(JWT::ExpiredSignature, 'Signature has expired')
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def verify_iat
|
44
|
+
return unless @payload.include?('iat')
|
45
|
+
|
46
|
+
if !(@payload['iat'].is_a?(Numeric)) || @payload['iat'].to_f > (Time.now.to_f + leeway)
|
47
|
+
fail(JWT::InvalidIatError, 'Invalid iat')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def verify_iss
|
52
|
+
return unless (options_iss = extract_option(:iss))
|
53
|
+
|
54
|
+
if @payload['iss'].to_s != options_iss.to_s
|
55
|
+
fail(
|
56
|
+
JWT::InvalidIssuerError,
|
57
|
+
"Invalid issuer. Expected #{options_iss}, received #{@payload['iss'] || '<none>'}"
|
58
|
+
)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def verify_jti
|
63
|
+
options_verify_jti = extract_option(:verify_jti)
|
64
|
+
if options_verify_jti.respond_to?(:call)
|
65
|
+
fail(JWT::InvalidJtiError, 'Invalid jti') unless options_verify_jti.call(@payload['jti'])
|
66
|
+
else
|
67
|
+
fail(JWT::InvalidJtiError, 'Missing jti') if @payload['jti'].to_s.strip.empty?
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def verify_not_before
|
72
|
+
return unless @payload.include?('nbf')
|
73
|
+
|
74
|
+
if @payload['nbf'].to_i > (Time.now.to_i + leeway)
|
75
|
+
fail(JWT::ImmatureSignature, 'Signature nbf has not been reached')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def verify_sub
|
80
|
+
return unless (options_sub = extract_option(:sub))
|
81
|
+
|
82
|
+
fail(
|
83
|
+
JWT::InvalidSubError,
|
84
|
+
"Invalid subject. Expected #{options_sub}, received #{@payload['sub'] || '<none>'}"
|
85
|
+
) unless @payload['sub'].to_s == options_sub.to_s
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def extract_option(key)
|
91
|
+
@options.values_at(key.to_sym, key.to_s).compact.first
|
92
|
+
end
|
93
|
+
|
94
|
+
def leeway
|
95
|
+
extract_option :leeway
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/lib/jwt/version.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# Moments version builder module
|
4
|
+
module JWT
|
5
|
+
def self.gem_version
|
6
|
+
Gem::Version.new VERSION::STRING
|
7
|
+
end
|
8
|
+
|
9
|
+
# Moments version builder module
|
10
|
+
module VERSION
|
11
|
+
# major version
|
12
|
+
MAJOR = 1
|
13
|
+
# minor version
|
14
|
+
MINOR = 5
|
15
|
+
# tiny version
|
16
|
+
TINY = 4
|
17
|
+
# alpha, beta, etc. tag
|
18
|
+
PRE = nil
|
19
|
+
|
20
|
+
# Build version string
|
21
|
+
STRING = [MAJOR, MINOR, TINY, PRE].compact.join('.')
|
22
|
+
end
|
23
|
+
end
|
data/ruby-jwt.gemspec
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
lib = File.expand_path('../lib/', __FILE__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'jwt/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'jwt'
|
7
|
+
spec.version = JWT.gem_version
|
8
|
+
spec.authors = [
|
9
|
+
'Jeff Lindsay',
|
10
|
+
'Tim Rudat'
|
11
|
+
]
|
12
|
+
spec.email = 'timrudat@gmail.com'
|
13
|
+
spec.summary = 'JSON Web Token implementation in Ruby'
|
14
|
+
spec.description = 'A pure ruby implementation of the RFC 7519 OAuth JSON Web Token (JWT) standard.'
|
15
|
+
spec.homepage = 'http://github.com/jwt/ruby-jwt'
|
16
|
+
spec.license = 'MIT'
|
17
|
+
|
18
|
+
spec.files = `git ls-files -z`.split("\x0")
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
21
|
+
spec.require_paths = %w(lib)
|
22
|
+
|
23
|
+
spec.add_development_dependency 'bundler'
|
24
|
+
spec.add_development_dependency 'rake'
|
25
|
+
spec.add_development_dependency 'rspec'
|
26
|
+
spec.add_development_dependency 'simplecov'
|
27
|
+
spec.add_development_dependency 'simplecov-json'
|
28
|
+
spec.add_development_dependency 'codeclimate-test-reporter'
|
29
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
-----BEGIN EC PARAMETERS-----
|
2
|
+
BggqhkjOPQMBBw==
|
3
|
+
-----END EC PARAMETERS-----
|
4
|
+
-----BEGIN EC PRIVATE KEY-----
|
5
|
+
MHcCAQEEIJmVse5uPfj6B4TcXrUAvf9/8pJh+KrKKYLNcmOnp/vPoAoGCCqGSM49
|
6
|
+
AwEHoUQDQgAEAr+WbDE5VtIDGhtYMxvEc6cMsDBc/DX1wuhIMu8dQzOLSt0tpqK9
|
7
|
+
MVfXbVfrKdayVFgoWzs8MilcYq0QIhKx/w==
|
8
|
+
-----END EC PRIVATE KEY-----
|
@@ -0,0 +1,8 @@
|
|
1
|
+
-----BEGIN EC PARAMETERS-----
|
2
|
+
BgUrgQQACg==
|
3
|
+
-----END EC PARAMETERS-----
|
4
|
+
-----BEGIN EC PRIVATE KEY-----
|
5
|
+
MHQCAQEEICfA4AaomONdmPTzeyrx5U/jugYXTERyb5U3ETTv7Hx7oAcGBSuBBAAK
|
6
|
+
oUQDQgAEPmuXZT3jpJnEMVPOW6RMsmxeGLOCE1PN6fwvUwOsxv7YnyoQ5/bpo64n
|
7
|
+
+Jp4slSl1aUNoCBF2oz9bS0iyBo3jg==
|
8
|
+
-----END EC PRIVATE KEY-----
|
@@ -0,0 +1,9 @@
|
|
1
|
+
-----BEGIN EC PARAMETERS-----
|
2
|
+
BgUrgQQAIg==
|
3
|
+
-----END EC PARAMETERS-----
|
4
|
+
-----BEGIN EC PRIVATE KEY-----
|
5
|
+
MIGkAgEBBDDxOljqUKw9YNhkluSJIBAYO1YXcNtS+vckd5hpTZ5toxsOlwbmyrnU
|
6
|
+
Tn+D5Xma1m2gBwYFK4EEACKhZANiAASQwYTiRvXu1hMHceSosMs/8uf50sJI3jvK
|
7
|
+
kdSkvuRAPxSzhtrUvCQDnVsThFq4aOdZZY1qh2ErJGtzmrx+pEsJvJnvfOTG3NGU
|
8
|
+
KRalek+LQfVqAUSvDMKlxdkz2e67tso=
|
9
|
+
-----END EC PRIVATE KEY-----
|
@@ -0,0 +1,9 @@
|
|
1
|
+
-----BEGIN EC PARAMETERS-----
|
2
|
+
BgUrgQQAIg==
|
3
|
+
-----END EC PARAMETERS-----
|
4
|
+
-----BEGIN EC PRIVATE KEY-----
|
5
|
+
MIGkAgEBBDAfZW47dSKnC5JkSVOk1ERxCIi/IJ1p1WBnVGx4hnrNHy+dxtaZJaF+
|
6
|
+
YLInFQ/QbYegBwYFK4EEACKhZANiAAQwXkx4BFBGLXbzl5yVrfxK7er8hSi38iDE
|
7
|
+
K2+7cdrR137Wn5JUnL4WTwXTzkyUgfBOL3sHNozwfgU03GD/EOUEKqzsIJiz2cbP
|
8
|
+
bFALd4hS+8T4szDLVC9Jl1W6k0CAtmM=
|
9
|
+
-----END EC PRIVATE KEY-----
|
@@ -0,0 +1,10 @@
|
|
1
|
+
-----BEGIN EC PARAMETERS-----
|
2
|
+
BgUrgQQAIw==
|
3
|
+
-----END EC PARAMETERS-----
|
4
|
+
-----BEGIN EC PRIVATE KEY-----
|
5
|
+
MIHcAgEBBEIB0/+ffxEj7j62xvGaB5pvzk888e412ESO/EK/K0QlS9dSF8+Rj1rG
|
6
|
+
zqpRB8fvDnoe8xdmkW/W5GKzojMyv7YQYumgBwYFK4EEACOhgYkDgYYABAEw74Yw
|
7
|
+
aTbPY6TtWmxx6LJDzCX2nKWCPnKdZcEH9Ncu8g5RjRBRq2yacja3OoS6nA2YeDng
|
8
|
+
reBJxZr376P6Ns6XcQFWDA6K/MCTrEBCsPxXZNxd8KR9vMGWhgNtWRrcKzwJfQkr
|
9
|
+
suyehZkbbYyFnAWyARKHZuV7VUXmeEmRS/f93MPqVA==
|
10
|
+
-----END EC PRIVATE KEY-----
|
@@ -0,0 +1,6 @@
|
|
1
|
+
-----BEGIN PUBLIC KEY-----
|
2
|
+
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQBMO+GMGk2z2Ok7VpsceiyQ8wl9pyl
|
3
|
+
gj5ynWXBB/TXLvIOUY0QUatsmnI2tzqEupwNmHg54K3gScWa9++j+jbOl3EBVgwO
|
4
|
+
ivzAk6xAQrD8V2TcXfCkfbzBloYDbVka3Cs8CX0JK7LsnoWZG22MhZwFsgESh2bl
|
5
|
+
e1VF5nhJkUv3/dzD6lQ=
|
6
|
+
-----END PUBLIC KEY-----
|
@@ -0,0 +1,10 @@
|
|
1
|
+
-----BEGIN EC PARAMETERS-----
|
2
|
+
BgUrgQQAIw==
|
3
|
+
-----END EC PARAMETERS-----
|
4
|
+
-----BEGIN EC PRIVATE KEY-----
|
5
|
+
MIHbAgEBBEG/KbA2oCbiCT6L3V8XSz2WKBy0XhGvIFbl/ZkXIXnkYt+1B7wViSVo
|
6
|
+
KCHuMFsi6xU/5nE1EuDG2UsQJmKeAMkIOKAHBgUrgQQAI6GBiQOBhgAEAG0TFWe5
|
7
|
+
cZ5DZIyfuysrCoQySTNxd+aT8sPIxsx7mW6YBTsuO6rEgxyegd2Auy4xtikxpzKv
|
8
|
+
soMXR02999Aaus2jAAt/wxrhhr41BDP4MV0b6Zngb72hna0pcGqit5OyU8AbOJUZ
|
9
|
+
+rdyowRGsOY+aPbOyVhdNcsEdxYC8GdIyCQLBC1H
|
10
|
+
-----END EC PRIVATE KEY-----
|
@@ -0,0 +1,6 @@
|
|
1
|
+
-----BEGIN PUBLIC KEY-----
|
2
|
+
MIGbMBAGByqGSM49AgEGBSuBBAAjA4GGAAQAbRMVZ7lxnkNkjJ+7KysKhDJJM3F3
|
3
|
+
5pPyw8jGzHuZbpgFOy47qsSDHJ6B3YC7LjG2KTGnMq+ygxdHTb330Bq6zaMAC3/D
|
4
|
+
GuGGvjUEM/gxXRvpmeBvvaGdrSlwaqK3k7JTwBs4lRn6t3KjBEaw5j5o9s7JWF01
|
5
|
+
ywR3FgLwZ0jIJAsELUc=
|
6
|
+
-----END PUBLIC KEY-----
|
@@ -0,0 +1,15 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIICXgIBAAKBgQDO/ahgFDvniFoQ1dm+MdnkBi+Ts5W9AtQNgw4ZHIdPnqEzSgW7
|
3
|
+
0opKEu8hnlLqsIyU2BC2op/xOanipdbXObuFlA6bth1cYRI+YJlR3BbPGOIL6YbJ
|
4
|
+
ud9m0gIsBlCDLm4e/E45ZS+emudISP7/SF7zxvxZlnr1z7HTm7nIIVBvuQIDAQAB
|
5
|
+
AoGBAMzFQAccvU6GI6O4C5sOsiHUxMh3xtCftaxQVGgfQvVPVuXoeteep1Q0ewFl
|
6
|
+
IV4vnkO5pH8pTtVTWG9x5KIy6QCql4qvr2jkOm4mo9uogrpNklvBl2lN4Lxubj0N
|
7
|
+
mGRXaM3hckZl8+JT6uzfBfjy+pd8AOigJGPQCOZn4gmANW7pAkEA82Nh4wpj6ZRU
|
8
|
+
NBiBq3ONZuH4xJm59MI2FWRJsGUFUYdSaFwyKKim52/13d8iUb7v9utWQFRatCXz
|
9
|
+
Lqw9fQyVrwJBANm3dBOVxpUPrYEQsG0q2rdP+u6U3woylxwtQgJxImZKZmmJlPr8
|
10
|
+
9v23rhydvCe1ERPYe7EjF4RGWVPN3KLdExcCQDdzNfL3BApMS97OkoRQQC/nXbjU
|
11
|
+
2SPlN1MqVQuGCG8pqGG0V40h11y1CkvxMS10ldEojq77SOrwFnZUsXGS82sCQQC6
|
12
|
+
XdO7QCaxSq5XIRYlHN4EtS40NLOIYy3/LK6osHel4GIyTVd+UjSLk0QzssJxqwln
|
13
|
+
V5TqWQO0cxPcLQiFUYEZAkEA2G84ilb9QXOgbNyoE1VifNk49hhodbSskLb86uwY
|
14
|
+
Vgtzq1ZsqoPBCasr4WRiXt270n+mo5dNYRlZwiUn9lH78Q==
|
15
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,6 @@
|
|
1
|
+
-----BEGIN PUBLIC KEY-----
|
2
|
+
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDO/ahgFDvniFoQ1dm+MdnkBi+T
|
3
|
+
s5W9AtQNgw4ZHIdPnqEzSgW70opKEu8hnlLqsIyU2BC2op/xOanipdbXObuFlA6b
|
4
|
+
th1cYRI+YJlR3BbPGOIL6YbJud9m0gIsBlCDLm4e/E45ZS+emudISP7/SF7zxvxZ
|
5
|
+
lnr1z7HTm7nIIVBvuQIDAQAB
|
6
|
+
-----END PUBLIC KEY-----
|
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEpAIBAAKCAQEA4GzZTLU48c4WbyvHi+QKrB71x+T0eq5hqDbQqnlYjhD1Ika7
|
3
|
+
io1iplsdJWJuyxfYbUkb2Ol0fj4koZ/GS6lgCZr4+8UHbr1qf0Eu5HZSpszs2YxY
|
4
|
+
8U5RHnrpw67co7hlgAR9HbyNf5XIYgLV9ldHH/eazwnc3F/hgNsV0xjScVilejgo
|
5
|
+
cJ4zcsyymvW8t42lteM7bI867ZuJhGop/V+Y0HFyrMsPoQyLuCUpr6ulOfrkr7ZO
|
6
|
+
dhAIG8r1HcjOp/AUjM15vfXcbUZjkM/VloifX1YitU3upMGJ8/DpFGffMOImrn5r
|
7
|
+
6BT494V8rRyN2qvQoAkLJpqZ0avLxwiR2lgVQQIDAQABAoIBAEH0Ozgr2fxWEInD
|
8
|
+
V/VooypKPvjr9F1JejGxSkmPN9MocKIOH3dsbZ1uEXa3ItBUxan4XlK06SNgp+tH
|
9
|
+
xULfF/Y6sQlsse59hBq50Uoa69dRShn1AP6JgZVvkduMPBNxUYL5zrs6emsQXb9Q
|
10
|
+
DglDRQfEAJ7vyxSIqQDxYcyT8uSUF70dqFe+E9B2VE3D6ccHc98k41pJrAFAUFH1
|
11
|
+
wwvDhfyYr7/Ultut9wzpZvU1meF3Vna3GOUHfxrG6wu1G+WIWHGjouzThsc1qiVI
|
12
|
+
BtMCJxuCt5fOXRbU4STbMqhB6sZHiOh6J/dZU6JwRYt+IS8FB6kCNFSEWZWQledJ
|
13
|
+
XqtYSQECgYEA9nmnFTRj3fTBq9zMXfCRujkSy6X2bOb39ftNXzHFuc+I6xmv/3Bs
|
14
|
+
P9tDdjueP/SnCb7i/9hXkpEIcxjrjiqgcvD2ym1hE4q+odMzRAXYMdnmzI34SVZE
|
15
|
+
U5hYJcYsXNKrTTleba7QgqdORmyJ9FwqLO40udvmrZMY223XDwgRkOkCgYEA6RkO
|
16
|
+
5wjjrWWp/G1YN3KXZTS1m2/eGrUThohXKAfAjbWWiouNLW2msXrxEWsPRL6xKiHu
|
17
|
+
X9cwZwzi3MstAgk+bphUGUVUkGKNDjWHJA25tDYjbPtkd6xbL4eCHsKpNL3HNYr9
|
18
|
+
N0CIvgn7qjaHRBem0iK7T6keY4axaSVddEwYapkCgYEA13K5qaB1F4Smcpt8DTWH
|
19
|
+
vPe8xUUaZlFzOJLmLCsuwmB2N8Ppg2j7RspcaxJsH021YaB5ftjWm+ipMSr8ZPY/
|
20
|
+
8JlPsNzxuYpTXtNmAbT2KYVm6THEch61dTk6/DIBf1YrpUJbl5by7vJeStL/uBmE
|
21
|
+
SGgksL5XIyzs0opuLdaIvFkCgYAyBLWE8AxjFfCvAQuwAj/ocLITo6KmWnrRIIqL
|
22
|
+
RXaVMgUWv7FQsTnW1cnK8g05tC2yG8vZ9wQk6Mf5lwOWb0NdWgSZ0528ydj41pWk
|
23
|
+
L+nMeN2LMjqxz2NVxJ8wWJcUgTCxFZ0WcRumo9/D+6V1ABpE9zz4cBLcSnfhVypB
|
24
|
+
nV6T6QKBgQCSZNCQ9HPxjAgYcsqc5sjNwuN1GHQZSav3Tye3k6zHENe1lsteT9K8
|
25
|
+
xciGIuhybKZBvB4yImIIHCtnH+AS+mHAGqHarjNDMfvjOq0dMibPx4+bkIiHdBIH
|
26
|
+
Xz+j5kmntvFiUnzr0Z/Tcqo+r8FvyCo1YWgwqGP8XoFrswD7gy7cZw==
|
27
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,9 @@
|
|
1
|
+
-----BEGIN PUBLIC KEY-----
|
2
|
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4GzZTLU48c4WbyvHi+QK
|
3
|
+
rB71x+T0eq5hqDbQqnlYjhD1Ika7io1iplsdJWJuyxfYbUkb2Ol0fj4koZ/GS6lg
|
4
|
+
CZr4+8UHbr1qf0Eu5HZSpszs2YxY8U5RHnrpw67co7hlgAR9HbyNf5XIYgLV9ldH
|
5
|
+
H/eazwnc3F/hgNsV0xjScVilejgocJ4zcsyymvW8t42lteM7bI867ZuJhGop/V+Y
|
6
|
+
0HFyrMsPoQyLuCUpr6ulOfrkr7ZOdhAIG8r1HcjOp/AUjM15vfXcbUZjkM/Vloif
|
7
|
+
X1YitU3upMGJ8/DpFGffMOImrn5r6BT494V8rRyN2qvQoAkLJpqZ0avLxwiR2lgV
|
8
|
+
QQIDAQAB
|
9
|
+
-----END PUBLIC KEY-----
|
@@ -0,0 +1,27 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
MIIEpAIBAAKCAQEAzHAVGaW9j4l3/b4ngcjjoIoIcnsQEWOMqErb5VhLZMGIq1gE
|
3
|
+
O5qxPDAwooKsNotzcAOB3ZyLn7p5D+dmOrNUYkYWgYITNGeSifrnVqQugd5Fh1L8
|
4
|
+
K7zOGltUo2UtjbN4uJ56tzxBMZp2wejs2/Qu0eu0xZK3To+YkDcWOk92rmNgmUSQ
|
5
|
+
C/kNyIOj+yBvOo3wTk6HvbhoIarCgJ6Lay1v/hMLyQLzwRY/Qfty1FTIDyTv2dch
|
6
|
+
47FsfkZ1KAL+MbUnHuCBPzGxRjXa8Iy9Z7YGxrYasUt1b0um64bscxoIiCu8yLL8
|
7
|
+
jlg01Rwrjr/MTwKRhwXlMp8B7HTonwtaG6arJwIDAQABAoIBAGFR4dmJusl/qW1T
|
8
|
+
fj8cQLAFxaupxaZhe24J5NAyzgEy2Dqo9ariIwkB78UM66ozjEqAgOvcP+NTw5m8
|
9
|
+
kD/VapA1yTTxlO7XdzzUAhiOo80S4IphCMZRZNPLMmluGtdf3lIUr1pXBrn0TCBX
|
10
|
+
H5o9jaREzpNXGof9d6T/dEdh2J9+uE/p1xE5GSxQfaPheZzCG7636La/DcArg/UR
|
11
|
+
+TusPqp62BEmk96pE/KKJRmEeH+WnPfSh6sMpLxi3hkEU7AynpliGT6Z6xV4csBI
|
12
|
+
S/rdpkcj5DWpbnQzkwdrnL2Q+POEq/vlx5/NlezvtQPNLvQWDyY4yBCoMKGb3EbX
|
13
|
+
xrxP7MECgYEA/kwe4P0Mqk+087IyhjDBGPfcMt8gfYc9nzNfIYSWdSwuSag/hqHq
|
14
|
+
I4GwHQzUV9ix3iM6w5hin10yAzWxCYZg9hquV+lSvNNpGB76FX6oOqwuAhyQMRwv
|
15
|
+
eW+VUyfFXeJugwL5JuIaNTvwPpQVDHYtELLifie+uzJ5HC6dhg/XchcCgYEAzc5/
|
16
|
+
+IXjOlExd/mBgFk/5Y87ifA0ZOgbaJXifYgU0aNSgz1piHxU3n2p4jJ9lSdwwCl2
|
17
|
+
Fb5EN7666t20PL5QcXJ5ZdaTRLzRlYiqTWzfYHBgttbB1Jl3Ed9GsKuzRgaRqGFC
|
18
|
+
ANJSqZlKG0NZ3keRtuKdFwq+IVOnsQr9g0TZiXECgYEAqUgtCiMKCloTIGMQpSnR
|
19
|
+
cXiWWjsUmturls4Q1vQ3YHrvuVLKLyqb/dT4Uu5WcMAs765OESThCit0/pQAbVHK
|
20
|
+
PCpYwubskAzAGjGM00BEZwJ1gixXhIm5xMIWCowgI7Z3ULlq+IptXeCvtkjHlksZ
|
21
|
+
BtO+WLLGkkEwRCV38WWcSzMCgYA/Xxqgl/mD94RYAQgTUWgPc69Nph08BQyLg7ue
|
22
|
+
E8z1UGkT6FEaqc4oRGGPOSTaTK63PQ0TXOb8k0pTD7l0CtYSWMFwzkXCoLGYbeCi
|
23
|
+
vqd5tqDRLAe7QxYa9rl5pSUqptMrGeeNATZa6sya4H5Hp5oCyny8n54z/OJh7ZRq
|
24
|
+
W0TwwQKBgQDDP7ksm2pcqadaVAmODdOlaDHbaEcxp8wN7YVz0lM3UpJth96ukbj7
|
25
|
+
S39eJhXYWOn6oJQb/lN9fGOYqjg3y6IchGZDp67ATvWYvn/NY0R7mt4K4oHx5TuN
|
26
|
+
rSQlP3WmOGv8Kemw892uRfW/jZyBEHhsfS213WDttVPn9F635GdNWw==
|
27
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,9 @@
|
|
1
|
+
-----BEGIN PUBLIC KEY-----
|
2
|
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAzHAVGaW9j4l3/b4ngcjj
|
3
|
+
oIoIcnsQEWOMqErb5VhLZMGIq1gEO5qxPDAwooKsNotzcAOB3ZyLn7p5D+dmOrNU
|
4
|
+
YkYWgYITNGeSifrnVqQugd5Fh1L8K7zOGltUo2UtjbN4uJ56tzxBMZp2wejs2/Qu
|
5
|
+
0eu0xZK3To+YkDcWOk92rmNgmUSQC/kNyIOj+yBvOo3wTk6HvbhoIarCgJ6Lay1v
|
6
|
+
/hMLyQLzwRY/Qfty1FTIDyTv2dch47FsfkZ1KAL+MbUnHuCBPzGxRjXa8Iy9Z7YG
|
7
|
+
xrYasUt1b0um64bscxoIiCu8yLL8jlg01Rwrjr/MTwKRhwXlMp8B7HTonwtaG6ar
|
8
|
+
JwIDAQAB
|
9
|
+
-----END PUBLIC KEY-----
|
@@ -0,0 +1,51 @@
|
|
1
|
+
-----BEGIN RSA PRIVATE KEY-----
|
2
|
+
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
|
51
|
+
-----END RSA PRIVATE KEY-----
|
@@ -0,0 +1,14 @@
|
|
1
|
+
-----BEGIN PUBLIC KEY-----
|
2
|
+
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqETmgWBi5rCmb7euJplA
|
3
|
+
/9xs65+bncc9Yvs5zjyycXSW82JfRuyguGm0OvA2wog24dR4N2kT/87DcGtp5JqJ
|
4
|
+
WADVFNr+2V2r6i57/OMLruRpn3p2r95dmo0COE+BxPFl7XEBT8JbH57ZtpgcB3/x
|
5
|
+
kS14nLOWFf96hrXPlXJC+VMVKVZmA8k2LRh42vT5wUf4U0Doy/p7yFNSFFa6Q8ww
|
6
|
+
e4TBy/z/f+rhFD1w8rxlYjallee/ocm7bjZCwbJGMm7orLViqWfsFX3O35PeoJ5h
|
7
|
+
/7uJ7iRwvTFERkTdwWP/0BeKBeItBR3YFc2mut+V9W+WKRkMSL6Crc+oVSx3p8aB
|
8
|
+
7j9SZFzQiRtes4BYETpX1xl2mgIq5hvsFbLw7ESrlIodiwUMTrSIid2DQ6q80kv1
|
9
|
+
zXPr4+Id6L0sJLxPCaXnTmNtasSwyedJJYxLjwhHJwtzFAeaq18H3O791YKhjAJ6
|
10
|
+
YxK3zJ59jTE6Pkvqjq183f2PGHVRvgSN7aCmI6MBUUB5wDP2K8zX2sh40/uPDVSd
|
11
|
+
6ei1vl3DpPk+h8iExx6AzbohfqZ+5RUUNx127L3MaQvOVC5TxV+R99gwKW++wzcV
|
12
|
+
uO3m2KqVUj+K1uYBy3KBCUMBbckpEWGbN++jcdV5oJX6fsC66nOmKlntYwCL/pRw
|
13
|
+
w+oLsbzF8J3dxeDbKNF9JDsCAwEAAQ==
|
14
|
+
-----END PUBLIC KEY-----
|
@@ -0,0 +1,175 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'jwt/verify'
|
3
|
+
|
4
|
+
module JWT
|
5
|
+
RSpec.describe Verify do
|
6
|
+
let(:base_payload) { { 'user_id' => 'some@user.tld' } }
|
7
|
+
let(:options) { { leeway: 0} }
|
8
|
+
|
9
|
+
context '.verify_aud(payload, options)' do
|
10
|
+
let(:scalar_aud) { 'ruby-jwt-audience' }
|
11
|
+
let(:array_aud) { %w(ruby-jwt-aud test-aud ruby-ruby-ruby) }
|
12
|
+
let(:scalar_payload) { base_payload.merge('aud' => scalar_aud) }
|
13
|
+
let(:array_payload) { base_payload.merge('aud' => array_aud) }
|
14
|
+
|
15
|
+
it 'must raise JWT::InvalidAudError when the singular audience does not match' do
|
16
|
+
expect do
|
17
|
+
Verify.verify_aud(scalar_payload, options.merge(aud: 'no-match'))
|
18
|
+
end.to raise_error JWT::InvalidAudError
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'must raise JWT::InvalidAudError when the payload has an array and none match the supplied value' do
|
22
|
+
expect do
|
23
|
+
Verify.verify_aud(array_payload, options.merge(aud: 'no-match'))
|
24
|
+
end.to raise_error JWT::InvalidAudError
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'must raise JWT::InvalidAudError when the singular audience does not match and the options aud key is a string' do
|
28
|
+
expect do
|
29
|
+
Verify.verify_aud(scalar_payload, options.merge('aud' => 'no-match'))
|
30
|
+
end.to raise_error JWT::InvalidAudError
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'must allow a matching singular audience to pass' do
|
34
|
+
Verify.verify_aud(scalar_payload, options.merge(aud: scalar_aud))
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'must allow a matching audence to pass when the options key is a string' do
|
38
|
+
Verify.verify_aud(scalar_payload, options.merge('aud' => scalar_aud))
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'must allow an array with any value matching the one in the options' do
|
42
|
+
Verify.verify_aud(array_payload, options.merge(aud: array_aud.first))
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'must allow an array with any value matching the one in the options with a string options key' do
|
46
|
+
Verify.verify_aud(array_payload, options.merge('aud' => array_aud.first))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context '.verify_expiration(payload, options)' do
|
51
|
+
let(:leeway) { 10 }
|
52
|
+
let(:payload) { base_payload.merge('exp' => (Time.now.to_i - 5)) }
|
53
|
+
|
54
|
+
it 'must raise JWT::ExpiredSignature when the token has expired' do
|
55
|
+
expect do
|
56
|
+
Verify.verify_expiration(payload, options)
|
57
|
+
end.to raise_error JWT::ExpiredSignature
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'must allow some leeway in the expiration when configured' do
|
61
|
+
Verify.verify_expiration(payload, options.merge(leeway: 10))
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context '.verify_iat(payload, options)' do
|
66
|
+
let(:iat) { Time.now.to_f }
|
67
|
+
let(:payload) { base_payload.merge('iat' => iat) }
|
68
|
+
|
69
|
+
it 'must allow a valid iat' do
|
70
|
+
Verify.verify_iat(payload, options)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'must allow configured leeway' do
|
74
|
+
Verify.verify_iat(payload.merge('iat' => (iat + 60)), options.merge(leeway: 70))
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'must properly handle integer times' do
|
78
|
+
Verify.verify_iat(payload.merge('iat' => Time.now.to_i), options)
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'must raise JWT::InvalidIatError when the iat value is not Numeric' do
|
82
|
+
expect do
|
83
|
+
Verify.verify_iat(payload.merge('iat' => 'not a number'), options)
|
84
|
+
end.to raise_error JWT::InvalidIatError
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'must raise JWT::InvalidIatError when the iat value is in the future' do
|
88
|
+
expect do
|
89
|
+
Verify.verify_iat(payload.merge('iat' => (iat + 120)), options)
|
90
|
+
end.to raise_error JWT::InvalidIatError
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context '.verify_iss(payload, options)' do
|
95
|
+
let(:iss) { 'ruby-jwt-gem' }
|
96
|
+
let(:payload) { base_payload.merge('iss' => iss) }
|
97
|
+
|
98
|
+
let(:invalid_token) { JWT.encode base_payload, payload[:secret] }
|
99
|
+
|
100
|
+
it 'must raise JWT::InvalidIssuerError when the configured issuer does not match the payload issuer' do
|
101
|
+
expect do
|
102
|
+
Verify.verify_iss(payload, options.merge(iss: 'mismatched-issuer'))
|
103
|
+
end.to raise_error JWT::InvalidIssuerError
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'must raise JWT::InvalidIssuerError when the payload does not include an issuer' do
|
107
|
+
expect do
|
108
|
+
Verify.verify_iss(base_payload, options.merge(iss: iss))
|
109
|
+
end.to raise_error(JWT::InvalidIssuerError, /received <none>/)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'must allow a matching issuer to pass' do
|
113
|
+
Verify.verify_iss(payload, options.merge(iss: iss))
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
context '.verify_jti(payload, options)' do
|
118
|
+
let(:payload) { base_payload.merge('jti' => 'some-random-uuid-or-whatever') }
|
119
|
+
|
120
|
+
it 'must allow any jti when the verfy_jti key in the options is truthy but not a proc' do
|
121
|
+
Verify.verify_jti(payload, options.merge(verify_jti: true))
|
122
|
+
end
|
123
|
+
|
124
|
+
it 'must raise JWT::InvalidJtiError when the jti is missing' do
|
125
|
+
expect do
|
126
|
+
Verify.verify_jti(base_payload, options)
|
127
|
+
end.to raise_error JWT::InvalidJtiError, /missing/i
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'must raise JWT::InvalidJtiError when the jti is an empty string' do
|
131
|
+
expect do
|
132
|
+
Verify.verify_jti(base_payload.merge('jti' => ' '), options)
|
133
|
+
end.to raise_error JWT::InvalidJtiError, /missing/i
|
134
|
+
end
|
135
|
+
|
136
|
+
it 'must raise JWT::InvalidJtiError when verify_jti proc returns false' do
|
137
|
+
expect do
|
138
|
+
Verify.verify_jti(payload, options.merge(verify_jti: ->(jti) { false }))
|
139
|
+
end.to raise_error JWT::InvalidJtiError, /invalid/i
|
140
|
+
end
|
141
|
+
|
142
|
+
it 'true proc should not raise JWT::InvalidJtiError' do
|
143
|
+
Verify.verify_jti(payload, options.merge(verify_jti: ->(jti) { true }))
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
context '.verify_not_before(payload, options)' do
|
148
|
+
let(:payload) { base_payload.merge('nbf' => (Time.now.to_i + 5)) }
|
149
|
+
|
150
|
+
it 'must raise JWT::ImmatureSignature when the nbf in the payload is in the future' do
|
151
|
+
expect do
|
152
|
+
Verify.verify_not_before(payload, options)
|
153
|
+
end.to raise_error JWT::ImmatureSignature
|
154
|
+
end
|
155
|
+
|
156
|
+
it 'must allow some leeway in the token age when configured' do
|
157
|
+
Verify.verify_not_before(payload, options.merge(leeway: 10))
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
context '.verify_sub(payload, options)' do
|
162
|
+
let(:sub) { 'ruby jwt subject' }
|
163
|
+
|
164
|
+
it 'must raise JWT::InvalidSubError when the subjects do not match' do
|
165
|
+
expect do
|
166
|
+
Verify.verify_sub(base_payload.merge('sub' => 'not-a-match'), options.merge(sub: sub))
|
167
|
+
end.to raise_error JWT::InvalidSubError
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'must allow a matching sub' do
|
171
|
+
Verify.verify_sub(base_payload.merge('sub' => sub), options.merge(sub: sub))
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|