auth0_rs256_jwt_verifier 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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