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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 62a95cfb84c90e4b8059e318f2c7bfcee71e8b27
4
- data.tar.gz: 9e6cde7f7da12eeb4ddde673900eb9eb18b2a5d3
2
+ SHA256:
3
+ metadata.gz: 3fb88a4efe73c0b27347ec0cd00883c67b078562795459506eac11c292347fde
4
+ data.tar.gz: 2419bc74be68cb430969eda6ce87fcfe2049b47b28827fecf03963846533dbc6
5
5
  SHA512:
6
- metadata.gz: e5d78f48de5792166fff6903c7f3740be6bf1f5bb279971deba1363ce5e5151866d22b09f74508fb44c50248193372ab345410b2af921a7f9ba493b3a8eefd4e
7
- data.tar.gz: 93a0adcddc9c89f60e846fe4331a1308d5c4c04d35098206d5cf105abea32ab06a2b36622cdda900e6d95cec243430bdfe8560f73e982153f682dcf591c8c397
6
+ metadata.gz: 22bb8c0f7f6da4538174141894cf620d037e770b4154c058900d3ed49069f30e053f168fa1cf722830150f252b1a711d2734691b27822290735ca90acce5644e
7
+ data.tar.gz: f41860a5f7c5ec048fa2c27459183d75abbafe489be8818a6efbfbc476d8c894f8ab0e2814a63f5df6c0b7432e6f057ffb94bf0aab9ea741a7c70cd2ae16e692
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.6.0
4
+ - 2.4.1
5
+ - 2.3.1
6
+ - jruby
7
+ gemfile:
8
+ - gemfiles/json-jwt-1.7.gemfile
9
+ - gemfiles/json-jwt-1.10.gemfile
data/Gemfile CHANGED
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
  source "https://rubygems.org"
3
- ruby "~> 2.4.0"
4
3
 
5
4
  gem "minitest", "~> 5"
6
5
  gem "rake", "~> 12.0.0"
7
- gem "http", "~>2.2.2"
6
+ gem "http", "~> 4.1"
8
7
  gem "json-jwt", "~> 1.7.2"
data/README.md CHANGED
@@ -1,6 +1,44 @@
1
- # Auth0 JWT (RS256) verification library
1
+ [![Build Status](https://travis-ci.org/DroidsOnRoids/auth0_rs256_jwt_verifier.svg?branch=master)](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 = "auth0_rs256_jwt_verifier"
4
- s.version = "0.0.1"
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.files = `git ls-files`.split("\n")
18
- s.test_files = `git ls-files -- {test}/*`.split("\n")
19
- s.homepage = "https://rubygems.org/gems/auth0_rs256_jwt_verifier"
20
- s.license = "MIT"
21
- s.add_runtime_dependency "http", "~> 2"
22
- s.add_runtime_dependency "json-jwt", "~> 1.7"
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
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+ source "https://rubygems.org"
3
+
4
+ gem "minitest", "~> 5"
5
+ gem "rake", "~> 12.0.0"
6
+ gem "http", "~> 4.1"
7
+ gem "json-jwt", "~> 1.10.0"
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+ source "https://rubygems.org"
3
+
4
+ gem "minitest", "~> 5"
5
+ gem "rake", "~> 12.0.0"
6
+ gem "http", "~> 4.1"
7
+ gem "json-jwt", "~> 1.7.0"
@@ -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
@@ -2,7 +2,9 @@
2
2
  class Auth0RS256JWTVerifier
3
3
  class ExpVerifier
4
4
  def expired?(exp)
5
+ exp = Integer(exp)
5
6
  Time.at(exp).utc < Time.now.utc
6
7
  end
7
8
  end
9
+ private_constant :ExpVerifier
8
10
  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
@@ -9,6 +9,7 @@ class Auth0RS256JWTVerifier
9
9
  end
10
10
 
11
11
  def signed_with?(jwt_str, public_key)
12
+ jwt_str = String(jwt_str)
12
13
  JSON::JWT.decode(jwt_str, public_key)
13
14
  true
14
15
  rescue JSON::JWS::VerificationFailed
@@ -18,7 +18,7 @@ class Auth0RS256JWTVerifier
18
18
 
19
19
  class ValidAccessToken < Base
20
20
  def initialize(user_id)
21
- @user_id = user_id
21
+ @user_id = UserId.new(user_id)
22
22
  end
23
23
 
24
24
  attr_reader :user_id
@@ -24,4 +24,5 @@ class Auth0RS256JWTVerifier
24
24
  jwk.x5c.any?
25
25
  end
26
26
  end
27
+ private_constant :ValidJWKSet
27
28
  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 decodde simple jwt" do
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
- @http_stub = Object.new
104
+ http_stub = Object.new
105
105
  jwks = sample_jwks
106
- @http_stub.define_singleton_method(:get) { |*_| jwks }
107
- @http_stub
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
- @exp_verifier_stub = Object.new
112
- @exp_verifier_stub.define_singleton_method(:expired?) { |*_| expired }
113
- @exp_verifier_stub
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.1
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
- - lib/auth0_access_tokens_rs256_verifier.rb
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://rubygems.org/gems/auth0_rs256_jwt_verifier
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: '0'
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
- rubyforge_project:
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