auth0_rs256_jwt_verifier 0.0.1 → 0.0.2
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 +5 -5
- data/.travis.yml +9 -0
- data/Gemfile +1 -2
- data/README.md +39 -1
- data/auth0_rs256_jwt_verifier.gemspec +26 -20
- data/gemfiles/json-jwt-1.10.gemfile +7 -0
- data/gemfiles/json-jwt-1.7.gemfile +7 -0
- data/lib/auth0_rs256_jwt_verifier/certs_set.rb +2 -0
- data/lib/auth0_rs256_jwt_verifier/exp_verifier.rb +2 -0
- data/lib/auth0_rs256_jwt_verifier/jwk.rb +11 -10
- data/lib/auth0_rs256_jwt_verifier/jwk_set_downloader.rb +15 -14
- data/lib/auth0_rs256_jwt_verifier/jwt_decoder.rb +1 -0
- data/lib/auth0_rs256_jwt_verifier/results.rb +1 -1
- data/lib/auth0_rs256_jwt_verifier/valid_jwk_set.rb +1 -0
- data/test/auth0_rs256_jwt_verifier/exp_verifier_test.rb +19 -0
- data/test/auth0_rs256_jwt_verifier/jwt_decoder_test.rb +1 -1
- data/test/auth0_rs256_jwt_verifier_test.rb +6 -6
- metadata +12 -10
- data/lib/auth0_access_tokens_rs256_verifier.rb +0 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3fb88a4efe73c0b27347ec0cd00883c67b078562795459506eac11c292347fde
|
4
|
+
data.tar.gz: 2419bc74be68cb430969eda6ce87fcfe2049b47b28827fecf03963846533dbc6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 22bb8c0f7f6da4538174141894cf620d037e770b4154c058900d3ed49069f30e053f168fa1cf722830150f252b1a711d2734691b27822290735ca90acce5644e
|
7
|
+
data.tar.gz: f41860a5f7c5ec048fa2c27459183d75abbafe489be8818a6efbfbc476d8c894f8ab0e2814a63f5df6c0b7432e6f057ffb94bf0aab9ea741a7c70cd2ae16e692
|
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,44 @@
|
|
1
|
-
|
1
|
+
[](https://travis-ci.org/DroidsOnRoids/auth0_rs256_jwt_verifier)
|
2
|
+
|
3
|
+
# Auth0 JWT (RS256) verification library
|
2
4
|
[Auth0](https://auth0.com) is web service handling users identities which can be easily plugged
|
3
5
|
into your application. It provides [SDKs](https://auth0.com/docs) for many languages which enable you to sign up/in users
|
4
6
|
and returns access token ([JWT](https://jwt.io)) in exchange. Access token can be used then to access your's Web Service.
|
5
7
|
This gem helps you to [verify](https://auth0.com/docs/api-auth/tutorials/verify-access-token#verify-the-signature)
|
6
8
|
such access token which has been signed using the RS256 algorithm.
|
9
|
+
|
10
|
+
## Installation
|
11
|
+
Install the `auth0_rs256_jwt_verifier` package from [Rubygems](https://rubygems.org/gems/auth0_rs256_jwt_verifier):
|
12
|
+
|
13
|
+
```bash
|
14
|
+
gem install auth0_rs256_jwt_verifier
|
15
|
+
```
|
16
|
+
|
17
|
+
Install it using [Bundler](https://bundler.io/) specifying it as dependency in your Gemfile:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem "auth0_rs256_jwt_verifier"
|
21
|
+
```
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
```ruby
|
26
|
+
# Verifier caches RS256 certificates fetched from jwks_uri.
|
27
|
+
# You should initialize it once and reuse for JWTs verification.
|
28
|
+
|
29
|
+
require "auth0_rs256_jwt_verifier"
|
30
|
+
|
31
|
+
AUTH0_JWT_VERIFIER = Auth0RS256JWTVerifier.new(
|
32
|
+
issuer: "ISSUER",
|
33
|
+
audience: "AUDIENCE",
|
34
|
+
jwks_url: "https://YOUR_AUTH0_DOMAIN/.well-known/jwks.json"
|
35
|
+
)
|
36
|
+
|
37
|
+
result = AUTH0_JWT_VERIFIER.verify("JWT_ACCESS_TOKEN_SIGNED_USING_RS256_ALGORITHM").valid?
|
38
|
+
if result.valid?
|
39
|
+
p "Token is valid"
|
40
|
+
p "User id: #{result.user_id}"
|
41
|
+
else
|
42
|
+
p "Token is invalid"
|
43
|
+
end
|
44
|
+
```
|
@@ -1,25 +1,31 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
Gem::Specification.new do |s|
|
3
|
-
s.name
|
4
|
-
s.version
|
5
|
-
s.date
|
6
|
-
s.summary
|
7
|
-
s.description
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
s.authors
|
16
|
-
s.email
|
17
|
-
s.
|
18
|
-
s.
|
19
|
-
|
20
|
-
s.
|
21
|
-
s.
|
22
|
-
s.
|
3
|
+
s.name = "auth0_rs256_jwt_verifier"
|
4
|
+
s.version = "0.0.2"
|
5
|
+
s.date = "2017-06-12"
|
6
|
+
s.summary = "Auth0 JWT (RS256) verification library"
|
7
|
+
s.description = <<-DESCRIPTION.gsub(/\s+/, " ").strip
|
8
|
+
Auth0 (https://auth0.com) is web service handling users identities which can be easily plugged
|
9
|
+
into your application. It provides SDKs for many languages which enable you to sign up/in users
|
10
|
+
and returns access token (JWT) in exchange. Access token can be used then to access your's Web Service.
|
11
|
+
This gem helps you to verify
|
12
|
+
(https://auth0.com/docs/api-auth/tutorials/verify-access-token#verify-the-signature)
|
13
|
+
such access token which has been signed using the RS256 algorithm.
|
14
|
+
DESCRIPTION
|
15
|
+
s.authors = ["Krzysztof Zielonka"]
|
16
|
+
s.email = "krzysztof.zielonka@droidsonroids.pl"
|
17
|
+
s.license = "MIT"
|
18
|
+
s.homepage = "https://github.com/DroidsOnRoids/auth0_rs256_jwt_verifier"
|
19
|
+
|
20
|
+
s.files = `git ls-files`.split("\n")
|
21
|
+
s.test_files = `git ls-files -- {test}/*`.split("\n")
|
22
|
+
s.require_paths = ["lib"]
|
23
|
+
|
24
|
+
s.required_ruby_version = ">= 2.2.0"
|
25
|
+
|
26
|
+
s.add_runtime_dependency "http", ">= 2"
|
27
|
+
s.add_runtime_dependency "json-jwt", ">= 1.7"
|
28
|
+
|
23
29
|
s.add_development_dependency "rake", "~> 12"
|
24
30
|
s.add_development_dependency "minitest", "~> 5"
|
25
31
|
end
|
@@ -9,6 +9,7 @@ class Auth0RS256JWTVerifier
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def find(id)
|
12
|
+
id = String(id)
|
12
13
|
cert = certs.find { |c| c.id == id }
|
13
14
|
raise NotFoundError, "cert #{id} doesn't exist" if cert.nil?
|
14
15
|
cert.cert
|
@@ -28,4 +29,5 @@ class Auth0RS256JWTVerifier
|
|
28
29
|
OpenSSL::X509::Certificate.new(encoded)
|
29
30
|
end
|
30
31
|
end
|
32
|
+
private_constant :CertsSet
|
31
33
|
end
|
@@ -3,6 +3,16 @@ class Auth0RS256JWTVerifier
|
|
3
3
|
class JWK
|
4
4
|
ParseError = Class.new(RuntimeError)
|
5
5
|
|
6
|
+
def initialize(hash)
|
7
|
+
raise ParseError unless hash.is_a?(Hash)
|
8
|
+
%i(Alg Kty Use X5C N E Kid X5T).each do |field_name|
|
9
|
+
field = self.class.const_get(field_name).new(hash[String(field_name).downcase])
|
10
|
+
instance_variable_set("@#{String(field_name).downcase}", field)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
attr_reader :alg, :kty, :use, :x5c, :n, :e, :kid, :x5t
|
15
|
+
|
6
16
|
def inspect
|
7
17
|
"JWK(\n" \
|
8
18
|
"\talg: #{@alg},\n" \
|
@@ -124,15 +134,6 @@ class Auth0RS256JWTVerifier
|
|
124
134
|
@certificates.each { |cert| yield cert }
|
125
135
|
end
|
126
136
|
end
|
127
|
-
|
128
|
-
def initialize(hash)
|
129
|
-
raise ParseError unless hash.is_a?(Hash)
|
130
|
-
%i(Alg Kty Use X5C N E Kid X5T).each do |field_name|
|
131
|
-
field = self.class.const_get(field_name).new(hash[String(field_name).downcase])
|
132
|
-
instance_variable_set("@#{String(field_name).downcase}", field)
|
133
|
-
end
|
134
|
-
end
|
135
|
-
|
136
|
-
attr_reader :alg, :kty, :use, :x5c, :n, :e, :kid, :x5t
|
137
137
|
end
|
138
|
+
private_constant :JWK
|
138
139
|
end
|
@@ -3,6 +3,21 @@ class Auth0RS256JWTVerifier
|
|
3
3
|
class JWKSetDownloader
|
4
4
|
InvalidJWKSetError = Class.new(RuntimeError)
|
5
5
|
|
6
|
+
def initialize(http)
|
7
|
+
@http = http
|
8
|
+
end
|
9
|
+
|
10
|
+
def download(url)
|
11
|
+
url = String(url)
|
12
|
+
body = @http.get(url)
|
13
|
+
json = JSON.parse(body)
|
14
|
+
begin
|
15
|
+
JWKSet.new(json)
|
16
|
+
rescue JWKSet::ParseError
|
17
|
+
raise InvalidJWKSetError
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
6
21
|
class JWKSet
|
7
22
|
include Enumerable
|
8
23
|
|
@@ -22,20 +37,6 @@ class Auth0RS256JWTVerifier
|
|
22
37
|
end
|
23
38
|
end
|
24
39
|
private_constant :JWKSet
|
25
|
-
|
26
|
-
def initialize(http)
|
27
|
-
@http = http
|
28
|
-
end
|
29
|
-
|
30
|
-
def download(url)
|
31
|
-
body = @http.get(url)
|
32
|
-
json = JSON.parse(body)
|
33
|
-
begin
|
34
|
-
JWKSet.new(json)
|
35
|
-
rescue JWKSet::ParseError
|
36
|
-
raise InvalidJWKSetError
|
37
|
-
end
|
38
|
-
end
|
39
40
|
end
|
40
41
|
private_constant :JWKSetDownloader
|
41
42
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require "test_helper"
|
3
|
+
|
4
|
+
class Auth0RS256JWTVerifier
|
5
|
+
describe ExpVerifier do
|
6
|
+
before :each do
|
7
|
+
@verificator = ExpVerifier.new
|
8
|
+
end
|
9
|
+
|
10
|
+
it "classifies value 0 as expired time" do
|
11
|
+
assert @verificator.expired?(0)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "classifies future time as not expired" do
|
15
|
+
one_hour_from_now = (Time.now + 3600).to_i
|
16
|
+
refute @verificator.expired?(one_hour_from_now)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -7,7 +7,7 @@ class Auth0RS256JWTVerifier
|
|
7
7
|
@decoder = JWTDecoder.new
|
8
8
|
end
|
9
9
|
|
10
|
-
it "should
|
10
|
+
it "should decode simple jwt" do
|
11
11
|
jwt = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImlkMTIzNCJ9." \
|
12
12
|
"eyJzdWIiOiIxMjM0NTY3ODkwIiwiYXVkIjoiYXVkaWVuY2UiLCJpc3MiO" \
|
13
13
|
"iJpc3N1ZXIifQ.cp374RbcG-q8rTLxSoWtLK7dtn5cBa3_g4riKL9OSt0"
|
@@ -101,16 +101,16 @@ describe Auth0RS256JWTVerifier do
|
|
101
101
|
private
|
102
102
|
|
103
103
|
def http_stub
|
104
|
-
|
104
|
+
http_stub = Object.new
|
105
105
|
jwks = sample_jwks
|
106
|
-
|
107
|
-
|
106
|
+
http_stub.define_singleton_method(:get) { |*_| jwks }
|
107
|
+
http_stub
|
108
108
|
end
|
109
109
|
|
110
110
|
def exp_verifier_stub(expired: false)
|
111
|
-
|
112
|
-
|
113
|
-
|
111
|
+
exp_verifier_stub = Object.new
|
112
|
+
exp_verifier_stub.define_singleton_method(:expired?) { |*_| expired }
|
113
|
+
exp_verifier_stub
|
114
114
|
end
|
115
115
|
|
116
116
|
def sample_jwks
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: auth0_rs256_jwt_verifier
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Krzysztof Zielonka
|
@@ -14,28 +14,28 @@ dependencies:
|
|
14
14
|
name: http
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '2'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: json-jwt
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.7'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.7'
|
41
41
|
- !ruby/object:Gem::Dependency
|
@@ -79,11 +79,13 @@ extra_rdoc_files: []
|
|
79
79
|
files:
|
80
80
|
- ".gitignore"
|
81
81
|
- ".rubocop.yml"
|
82
|
+
- ".travis.yml"
|
82
83
|
- Gemfile
|
83
84
|
- README.md
|
84
85
|
- Rakefile
|
85
86
|
- auth0_rs256_jwt_verifier.gemspec
|
86
|
-
-
|
87
|
+
- gemfiles/json-jwt-1.10.gemfile
|
88
|
+
- gemfiles/json-jwt-1.7.gemfile
|
87
89
|
- lib/auth0_rs256_jwt_verifier.rb
|
88
90
|
- lib/auth0_rs256_jwt_verifier/certs_set.rb
|
89
91
|
- lib/auth0_rs256_jwt_verifier/exp_verifier.rb
|
@@ -95,13 +97,14 @@ files:
|
|
95
97
|
- lib/auth0_rs256_jwt_verifier/user_id.rb
|
96
98
|
- lib/auth0_rs256_jwt_verifier/valid_jwk_set.rb
|
97
99
|
- test/.rubocop.yml
|
100
|
+
- test/auth0_rs256_jwt_verifier/exp_verifier_test.rb
|
98
101
|
- test/auth0_rs256_jwt_verifier/jwt_decoder_test.rb
|
99
102
|
- test/auth0_rs256_jwt_verifier/jwt_decoder_wrapper_test.rb
|
100
103
|
- test/auth0_rs256_jwt_verifier_test.rb
|
101
104
|
- test/fixtures/sample_jwks.json
|
102
105
|
- test/fixtures/sample_jwks_2.json
|
103
106
|
- test/test_helper.rb
|
104
|
-
homepage: https://
|
107
|
+
homepage: https://github.com/DroidsOnRoids/auth0_rs256_jwt_verifier
|
105
108
|
licenses:
|
106
109
|
- MIT
|
107
110
|
metadata: {}
|
@@ -113,15 +116,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
113
116
|
requirements:
|
114
117
|
- - ">="
|
115
118
|
- !ruby/object:Gem::Version
|
116
|
-
version:
|
119
|
+
version: 2.2.0
|
117
120
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
121
|
requirements:
|
119
122
|
- - ">="
|
120
123
|
- !ruby/object:Gem::Version
|
121
124
|
version: '0'
|
122
125
|
requirements: []
|
123
|
-
|
124
|
-
rubygems_version: 2.6.8
|
126
|
+
rubygems_version: 3.0.1
|
125
127
|
signing_key:
|
126
128
|
specification_version: 4
|
127
129
|
summary: Auth0 JWT (RS256) verification library
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require "http"
|
3
|
-
require "json"
|
4
|
-
|
5
|
-
require "auth0_jwt_rs256_verifier/user_id"
|
6
|
-
require "auth0_jwt_rs256_verifier/results"
|
7
|
-
require "auth0_jwt_rs256_verifier/jwt_decoder"
|
8
|
-
require "auth0_jwt_rs256_verifier/jwt_decoder_wrapper"
|
9
|
-
require "auth0_jwt_rs256_verifier/jwk_set_downloader"
|
10
|
-
require "auth0_jwt_rs256_verifier/valid_jwk_set"
|
11
|
-
require "auth0_jwt_rs256_verifier/certs_set"
|
12
|
-
require "auth0_jwt_rs256_verifier/exp_verifier"
|
13
|
-
require "auth0_jwt_rs256_verifier/jwk"
|
14
|
-
|
15
|
-
class Auth0RS256JWTVerifier
|
16
|
-
def initialize(issuer:, audience:, jwks_url:, http: HTTP, exp_verifier: ExpVerifier.new)
|
17
|
-
@audience = audience
|
18
|
-
@issuer = issuer
|
19
|
-
@jwks_url = jwks_url
|
20
|
-
@jwks_downloader = JWKSetDownloader.new(http)
|
21
|
-
@exp_verifier = exp_verifier
|
22
|
-
@certificates = nil
|
23
|
-
end
|
24
|
-
|
25
|
-
def verify(access_token)
|
26
|
-
payload = JWTDecoderWrapper.new(
|
27
|
-
@audience,
|
28
|
-
@issuer,
|
29
|
-
certificates,
|
30
|
-
exp_verifier: @exp_verifier,
|
31
|
-
jwt_decoder: JWTDecoder.new,
|
32
|
-
).decode(access_token)
|
33
|
-
Results::ValidAccessToken.new(UserId.new(payload.sub))
|
34
|
-
rescue JWTDecoderWrapper::Error
|
35
|
-
Results::INVALID_ACCESS_TOKEN
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def certificates
|
41
|
-
return @certificates if @certificates
|
42
|
-
@certificates = CertsSet.new(ValidJWKSet.new(@jwks_downloader.download(@jwks_url)))
|
43
|
-
end
|
44
|
-
end
|