jwt 2.4.0.beta1 → 2.5.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 637320f6741edec8adfafb3513fdad0927b9c08271137e7ad47e2b7515a6b90a
4
- data.tar.gz: a089bc9ef99438988ef542135cdfaa68496fd645877200059ab461122816e11e
3
+ metadata.gz: a3098671a837e7b291103cde1921277c61ecaa0f0797b955e6adc65328498f0d
4
+ data.tar.gz: 3253833ac6d7743e40a5d5157b161cd0daecc9b77f61dfa7687d6b3da1be56ca
5
5
  SHA512:
6
- metadata.gz: bdf07ebbbadc38c80b6eda44a6571d7bd8f5c0d806cb1955295fa201f8a77f9faba55567e23825eaf23350eaef391e6c34a09666297b1fe7cd0178348fe93586
7
- data.tar.gz: 924d0f219493f2cf133753ca25fbd7682d7f307b7b3724a659c795ef864b9129137e2b6db8d3591f1a006c9925c325ff51f2a87f23ad0b1d6b198124135ce093
6
+ metadata.gz: 306c946b1199301a3f1000c8ffba4a77d07fd05dd83f769da86fd29f254827b5af8488a4b6a54b11f1f7f3a028cb88caafb7ed67528e7004c0337f6506e595ea
7
+ data.tar.gz: 57d1eba7a06bc9d9f9fcb76b42aa3808415af5020c53969b4cada890b1646e7d348a96ce18010ab0a978e42825febbeb7b3f205b72e8ce60ef90132cf5887599
@@ -13,43 +13,44 @@ jobs:
13
13
  timeout-minutes: 30
14
14
  runs-on: ubuntu-latest
15
15
  steps:
16
- - uses: actions/checkout@v2
16
+ - uses: actions/checkout@v3
17
17
  - name: Set up Ruby
18
18
  uses: ruby/setup-ruby@v1
19
19
  with:
20
- ruby-version: "2.7"
20
+ ruby-version: "3.0"
21
21
  bundler-cache: true
22
22
  - name: Run RuboCop
23
23
  run: bundle exec rubocop
24
24
  test:
25
+ name: ${{ matrix.os }} - Ruby ${{ matrix.ruby }}
26
+ runs-on: ${{ matrix.os }}
25
27
  strategy:
26
28
  fail-fast: false
27
29
  matrix:
30
+ os:
31
+ - ubuntu-20.04
28
32
  ruby:
29
- - 2.5
30
- - 2.6
31
- - 2.7
33
+ - "2.5"
34
+ - "2.6"
35
+ - "2.7"
32
36
  - "3.0"
33
- - 3.1
37
+ - "3.1"
34
38
  gemfile:
35
39
  - gemfiles/standalone.gemfile
36
40
  - gemfiles/openssl.gemfile
37
41
  - gemfiles/rbnacl.gemfile
38
42
  experimental: [false]
39
43
  include:
40
- - ruby: 2.7
41
- gemfile: 'gemfiles/rbnacl.gemfile'
42
- - ruby: "ruby-head"
43
- experimental: true
44
- - ruby: "truffleruby-head"
45
- experimental: true
46
- runs-on: ubuntu-20.04
44
+ - { os: ubuntu-20.04, ruby: "2.7", gemfile: 'gemfiles/rbnacl.gemfile', experimental: false }
45
+ - { os: ubuntu-22.04, ruby: "3.1", experimental: false }
46
+ - { os: ubuntu-20.04, ruby: "truffleruby-head", experimental: true }
47
+ - { os: ubuntu-22.04, ruby: "head", experimental: true }
47
48
  continue-on-error: ${{ matrix.experimental }}
48
49
  env:
49
50
  BUNDLE_GEMFILE: ${{ matrix.gemfile }}
50
51
 
51
52
  steps:
52
- - uses: actions/checkout@v2
53
+ - uses: actions/checkout@v3
53
54
 
54
55
  - name: Install libsodium
55
56
  run: |
data/.reek.yml ADDED
@@ -0,0 +1,22 @@
1
+ ---
2
+ detectors:
3
+ TooManyStatements:
4
+ max_statements: 10
5
+ UtilityFunction:
6
+ enabled: false
7
+ LongParameterList:
8
+ enabled: false
9
+ DuplicateMethodCall:
10
+ max_calls: 2
11
+ IrresponsibleModule:
12
+ enabled: false
13
+ NestedIterators:
14
+ max_allowed_nesting: 2
15
+ UnusedParameters:
16
+ enabled: false
17
+ FeatureEnvy:
18
+ enabled: false
19
+ ControlParameter:
20
+ enabled: false
21
+ UnusedPrivateMethod:
22
+ enabled: false
data/.rubocop.yml CHANGED
@@ -1,5 +1,3 @@
1
- inherit_from: .rubocop_todo.yml
2
-
3
1
  AllCops:
4
2
  TargetRubyVersion: 2.5
5
3
  NewCops: enable
@@ -21,43 +19,38 @@ Style/GuardClause:
21
19
  Style/IfUnlessModifier:
22
20
  Enabled: false
23
21
 
24
- Layout/SpaceInsideHashLiteralBraces:
25
- Enabled: false
26
-
27
22
  Style/Lambda:
28
23
  Enabled: false
29
24
 
30
25
  Style/RaiseArgs:
31
26
  Enabled: false
32
27
 
33
- Style/SignalException:
34
- Enabled: false
35
-
36
28
  Metrics/AbcSize:
37
29
  Max: 25
38
30
 
39
31
  Metrics/ClassLength:
40
- Max: 103
32
+ Max: 112
41
33
 
42
34
  Metrics/ModuleLength:
43
35
  Max: 100
44
36
 
45
- Layout/LineLength:
46
- Enabled: false
37
+ Metrics/MethodLength:
38
+ Max: 20
47
39
 
48
40
  Metrics/BlockLength:
49
41
  Exclude:
50
42
  - spec/**/*_spec.rb
51
43
 
52
- Metrics/MethodLength:
53
- Max: 15
54
-
55
- Style/SingleLineBlockParams:
44
+ Layout/LineLength:
56
45
  Enabled: false
57
46
 
58
47
  Layout/EndAlignment:
59
48
  EnforcedStyleAlignWith: variable
60
49
 
50
+ Layout/EmptyLineBetweenDefs:
51
+ Enabled: true
52
+ AllowAdjacentOneLineDefs: true
53
+
61
54
  Style/FormatString:
62
55
  Enabled: false
63
56
 
@@ -70,12 +63,5 @@ Layout/MultilineOperationIndentation:
70
63
  Style/WordArray:
71
64
  Enabled: false
72
65
 
73
- Style/RedundantSelf:
66
+ Gemspec/RequireMFA:
74
67
  Enabled: false
75
-
76
- Layout/HashAlignment:
77
- Enabled: true
78
- EnforcedLastArgumentHashStyle: always_ignore
79
-
80
- Style/TrivialAccessors:
81
- AllowPredicates: true
data/.sourcelevel.yml CHANGED
@@ -1,4 +1,3 @@
1
- styleguide: excpt/linters
2
1
  engines:
3
2
  reek:
4
3
  enabled: true
@@ -6,13 +5,13 @@ engines:
6
5
  enabled: true
7
6
  rubocop:
8
7
  enabled: true
9
- channel: rubocop-0-52
8
+ channel: latest
10
9
  duplication:
11
10
  config:
12
11
  languages:
13
12
  - ruby
14
13
  enabled: true
15
14
  remark-lint:
16
- enabled: true
15
+ enabled: false
17
16
  exclude_paths:
18
- - spec
17
+ - spec
data/CHANGELOG.md CHANGED
@@ -1,51 +1,50 @@
1
1
  # Changelog
2
2
 
3
- ## [v2.4.0](https://github.com/jwt/ruby-jwt/tree/v2.4.0) (2022-05-03)
4
3
 
5
- [Full Changelog](https://github.com/jwt/ruby-jwt/compare/v2.3.0...v2.4.0)
4
+ ## [v2.5.0](https://github.com/jwt/ruby-jwt/tree/v2.5.0) (NEXT)
6
5
 
7
- **Implemented enhancements:**
6
+ [Full Changelog](https://github.com/jwt/ruby-jwt/compare/v2.4.1...master)
8
7
 
9
- - Ensure presence of claims [\#244](https://github.com/jwt/ruby-jwt/issues/244)
10
- - Support verifying signature signed using x5c header [\#59](https://github.com/jwt/ruby-jwt/issues/59)
11
- - Add x5c header key finder [\#338](https://github.com/jwt/ruby-jwt/pull/338) ([bdewater](https://github.com/bdewater))
8
+ **Features:**
12
9
 
13
- **Security fixes:**
10
+ - Support JWK thumbprints as key ids [#481](https://github.com/jwt/ruby-jwt/pull/481) ([@anakinj](https://github.com/anakinj)).
11
+ - Your contribution here
14
12
 
15
- - Importing JWK then exporting results in different `kid` [\#313](https://github.com/jwt/ruby-jwt/issues/313)
13
+ **Fixes and enhancements:**
14
+ - Bring back the old Base64 (RFC2045) deocode mechanisms [#488](https://github.com/jwt/ruby-jwt/pull/488) ([@anakinj](https://github.com/anakinj)).
15
+ - Rescue RbNaCl exception for EdDSA wrong key [#491](https://github.com/jwt/ruby-jwt/pull/491) ([@n-studio](https://github.com/n-studio)).
16
+ - New parameter name for cases when kid is not found using JWK key loader proc [#501](https://github.com/jwt/ruby-jwt/pull/501) ([@anakinj](https://github.com/anakinj)).
17
+ - Fix NoMethodError when a 2 segment token is missing 'alg' header [#502](https://github.com/jwt/ruby-jwt/pull/502) ([@cmrd-senya](https://github.com/cmrd-senya)).
18
+ - Support OpenSSL >= 3.0 [#496](https://github.com/jwt/ruby-jwt/pull/496) ([@anakinj](https://github.com/anakinj)).
19
+ - Your contribution here
16
20
 
17
- **Closed issues:**
21
+ ## [v2.4.1](https://github.com/jwt/ruby-jwt/tree/v2.4.1) (2022-06-07)
18
22
 
19
- - Is there a way to decode a ES256 encoded JWT with a root certificate but without a public key or a private key? [\#471](https://github.com/jwt/ruby-jwt/issues/471)
20
- - Encode output with extra quote [\#469](https://github.com/jwt/ruby-jwt/issues/469)
21
- - Please release new gem version [\#444](https://github.com/jwt/ruby-jwt/issues/444)
22
- - HS512 signature verification fails for valid tokens [\#438](https://github.com/jwt/ruby-jwt/issues/438)
23
- - ArgumentError: invalid base64 while calling JWT::JWK.import\(hash\) [\#361](https://github.com/jwt/ruby-jwt/issues/361)
24
- - NoMethodError (undefined method `encode' for JsonWebToken:Module\) [\#329](https://github.com/jwt/ruby-jwt/issues/329)
23
+ [Full Changelog](https://github.com/jwt/ruby-jwt/compare/v2.4.0...v2.4.1)
25
24
 
26
- **Merged pull requests:**
25
+ **Fixes and enhancements:**
26
+ - Raise JWT::DecodeError on invalid signature [\#484](https://github.com/jwt/ruby-jwt/pull/484) ([@freakyfelt!](https://github.com/freakyfelt!)).
27
+
28
+ ## [v2.4.0](https://github.com/jwt/ruby-jwt/tree/v2.4.0) (2022-06-06)
29
+
30
+ [Full Changelog](https://github.com/jwt/ruby-jwt/compare/v2.3.0...v2.4.0)
27
31
 
28
- - Fix RuboCop TODOs [\#476](https://github.com/jwt/ruby-jwt/pull/476) ([typhoon2099](https://github.com/typhoon2099))
29
- - Update note about supported JWK types [\#475](https://github.com/jwt/ruby-jwt/pull/475) ([dpashkevich](https://github.com/dpashkevich))
30
- - Make specific algorithms in README linkable [\#472](https://github.com/jwt/ruby-jwt/pull/472) ([milieu](https://github.com/milieu))
31
- - Add tests for keyfinder logic to ensure the argument count does not matter [\#467](https://github.com/jwt/ruby-jwt/pull/467) ([anakinj](https://github.com/anakinj))
32
- - More tests for none token [\#466](https://github.com/jwt/ruby-jwt/pull/466) ([anakinj](https://github.com/anakinj))
33
- - Improve non algorithm tests [\#465](https://github.com/jwt/ruby-jwt/pull/465) ([anakinj](https://github.com/anakinj))
34
- - Bring back Ruby 2.5 support and CodeClimate coverage reports [\#464](https://github.com/jwt/ruby-jwt/pull/464) ([anakinj](https://github.com/anakinj))
35
- - Fix a little RuboCop issue [\#462](https://github.com/jwt/ruby-jwt/pull/462) ([anakinj](https://github.com/anakinj))
36
- - Fixes with latest RuboCop [\#459](https://github.com/jwt/ruby-jwt/pull/459) ([anakinj](https://github.com/anakinj))
37
- - Removed bundler-audit from codeclimate config [\#458](https://github.com/jwt/ruby-jwt/pull/458) ([anakinj](https://github.com/anakinj))
38
- - Updated rubocop to 1.23.0 [\#457](https://github.com/jwt/ruby-jwt/pull/457) ([anakinj](https://github.com/anakinj))
39
- - Add Ruby 3.1 to test matrix [\#456](https://github.com/jwt/ruby-jwt/pull/456) ([anakinj](https://github.com/anakinj))
40
- - Use Ruby built-in url-safe base64 methods [\#454](https://github.com/jwt/ruby-jwt/pull/454) ([bdewater](https://github.com/bdewater))
41
- - Stop running tests on EOL rubies. [\#453](https://github.com/jwt/ruby-jwt/pull/453) ([anakinj](https://github.com/anakinj))
42
- - Fix openssl gem version check to support versons greater than 3 [\#452](https://github.com/jwt/ruby-jwt/pull/452) ([anakinj](https://github.com/anakinj))
43
- - Readme: Typo fix re MissingRequiredClaim [\#451](https://github.com/jwt/ruby-jwt/pull/451) ([antonmorant](https://github.com/antonmorant))
44
- - Fix for exception after mergeing \#385 [\#450](https://github.com/jwt/ruby-jwt/pull/450) ([anakinj](https://github.com/anakinj))
45
- - Create CODE\_OF\_CONDUCT.md [\#449](https://github.com/jwt/ruby-jwt/pull/449) ([loic5](https://github.com/loic5))
46
- - Allow regular expressions and procs to verify issuer [\#437](https://github.com/jwt/ruby-jwt/pull/437) ([rewritten](https://github.com/rewritten))
47
- - Add Support to be able to verify from multiple keys [\#425](https://github.com/jwt/ruby-jwt/pull/425) ([ritikesh](https://github.com/ritikesh))
48
- - Define the secp256r1 curve [\#385](https://github.com/jwt/ruby-jwt/pull/385) ([anakinj](https://github.com/anakinj))
32
+ **Features:**
33
+
34
+ - Dropped support for Ruby 2.5 and older [#453](https://github.com/jwt/ruby-jwt/pull/453) - [@anakinj](https://github.com/anakinj).
35
+ - Use Ruby built-in url-safe base64 methods [#454](https://github.com/jwt/ruby-jwt/pull/454) - [@bdewater](https://github.com/bdewater).
36
+ - Updated rubocop to 1.23.0 [#457](https://github.com/jwt/ruby-jwt/pull/457) - [@anakinj](https://github.com/anakinj).
37
+ - Add x5c header key finder [#338](https://github.com/jwt/ruby-jwt/pull/338) - [@bdewater](https://github.com/bdewater).
38
+ - Author driven changelog process [#463](https://github.com/jwt/ruby-jwt/pull/463) - [@anakinj](https://github.com/anakinj).
39
+ - Allow regular expressions and procs to verify issuer [\#437](https://github.com/jwt/ruby-jwt/pull/437) ([rewritten](https://github.com/rewritten)).
40
+ - Add Support to be able to verify from multiple keys [\#425](https://github.com/jwt/ruby-jwt/pull/425) ([ritikesh](https://github.com/ritikesh)).
41
+
42
+ **Fixes and enhancements:**
43
+ - Readme: Typo fix re MissingRequiredClaim [\#451](https://github.com/jwt/ruby-jwt/pull/451) ([antonmorant](https://github.com/antonmorant)).
44
+ - Fix RuboCop TODOs [\#476](https://github.com/jwt/ruby-jwt/pull/476) ([typhoon2099](https://github.com/typhoon2099)).
45
+ - Make specific algorithms in README linkable [\#472](https://github.com/jwt/ruby-jwt/pull/472) ([milieu](https://github.com/milieu)).
46
+ - Update note about supported JWK types [\#475](https://github.com/jwt/ruby-jwt/pull/475) ([dpashkevich](https://github.com/dpashkevich)).
47
+ - Create CODE\_OF\_CONDUCT.md [\#449](https://github.com/jwt/ruby-jwt/pull/449) ([loic5](https://github.com/loic5)).
49
48
 
50
49
  ## [v2.3.0](https://github.com/jwt/ruby-jwt/tree/v2.3.0) (2021-10-03)
51
50
 
data/CONTRIBUTING.md ADDED
@@ -0,0 +1,99 @@
1
+ # Contributing to [ruby-jwt](https://github.com/jwt/ruby-jwt)
2
+
3
+ ## Forking the project
4
+
5
+ Fork the project on GitHub and clone your own fork. Instuctions on forking can be found from the [GitHub Docs](https://docs.github.com/en/get-started/quickstart/fork-a-repo)
6
+
7
+ ```
8
+ git clone git@github.com:you/ruby-jwt.git
9
+ cd ruby-jwt
10
+ git remote add upstream https://github.com/jwt/ruby-jwt
11
+ ```
12
+
13
+ ## Create a branch for your implementation
14
+
15
+ Make sure you have the latest upstream master branch of the project.
16
+
17
+ ```
18
+ git fetch --all
19
+ git checkout master
20
+ git rebase upstream/master
21
+ git push origin master
22
+ git checkout -b fix-a-little-problem
23
+ ```
24
+
25
+ ## Running the tests and linter
26
+
27
+ Before you start with your implementation make sure you are able to get a succesful test run with the current revision.
28
+
29
+ The tests are written with rspec and [Appraisal](https://github.com/thoughtbot/appraisal) is used to ensure compatibility with 3rd party dependencies providing cryptographic features.
30
+
31
+ [Rubocop](https://github.com/rubocop/rubocop) is used to enforce the Ruby style.
32
+
33
+ To run the complete set of tests and linter run the following
34
+
35
+ ```bash
36
+ bundle install
37
+ bundle exec appraisal rake test
38
+ bundle exec rubocop
39
+ ```
40
+
41
+ ## Implement your feature
42
+
43
+ Implement tests and your change. Don't be shy adding a little something in the [README](README.md).
44
+ Add a short description of the change in either the `Features` or `Fixes` section in the [CHANGELOG](CHANGELOG.md) file.
45
+
46
+ The form of the row (You need to return to the row when you know the pull request id)
47
+ ```
48
+ - Fix a little problem [#123](https://github.com/jwt/ruby-jwt/pull/123) - [@you](https://github.com/you).
49
+ ```
50
+
51
+ ## Push your branch and create a pull request
52
+
53
+ Before pushing make sure the tests pass and RuboCop is happy.
54
+
55
+ ```
56
+ bundle exec appraisal rake test
57
+ bundle exec rubocop
58
+ git push origin fix-a-little-problem
59
+ ```
60
+
61
+ Make a new pull request on the [ruby-jwt project](https://github.com/jwt/ruby-jwt/pulls) with a description what the change is about.
62
+
63
+ ## Update the CHANGELOG, again
64
+
65
+ Update the [CHANGELOG](CHANGELOG.md) with the pull request id from the previous step.
66
+
67
+ You can ammend the previous commit with the updated changelog change and force push your branch. The PR will get automatically updated.
68
+
69
+ ```
70
+ git add CHANGELOG.md
71
+ git commit --amend --no-edit
72
+ git push origin fix-a-little-problem -f
73
+ ```
74
+
75
+ ## Keep an eye on your pull request
76
+
77
+ A maintainer will review and probably merge you changes when time allows, be patient.
78
+
79
+ ## Keeping your branch up-to-date
80
+
81
+ It's recommended that you keep your branch up-to-date by rebasing to the upstream master.
82
+
83
+ ```
84
+ git fetch upstream
85
+ git checkout fix-a-little-problem
86
+ git rebase upstream/master
87
+ git push origin fix-a-little-problem -f
88
+ ```
89
+
90
+ # Releasing a new version
91
+
92
+ The version is using the [Semantic Versioning](http://semver.org/) and the version is located in the [version.rb](lib/jwt/version.rb) file.
93
+ Also update the [CHANGELOG](CHANGELOG.md) to reflect the upcoming version release.
94
+
95
+ ```bash
96
+ rake release
97
+ ```
98
+
99
+ **If you want a release cut with your PR, please include a version bump according to **
data/README.md CHANGED
@@ -12,10 +12,12 @@ A ruby implementation of the [RFC 7519 OAuth JSON Web Token (JWT)](https://tools
12
12
  If you have further questions related to development or usage, join us: [ruby-jwt google group](https://groups.google.com/forum/#!forum/ruby-jwt).
13
13
 
14
14
  ## Announcements
15
-
15
+ * Ruby 2.4 support was dropped in version 2.4.0
16
16
  * Ruby 1.9.3 support was dropped at December 31st, 2016.
17
17
  * Version 1.5.3 yanked. See: [#132](https://github.com/jwt/ruby-jwt/issues/132) and [#133](https://github.com/jwt/ruby-jwt/issues/133)
18
18
 
19
+ See [CHANGELOG.md](CHANGELOG.md) for a complete set of changes.
20
+
19
21
  ## Sponsors
20
22
 
21
23
  |Logo|Message|
@@ -130,19 +132,17 @@ puts decoded_token
130
132
  * ES256 - ECDSA using P-256 and SHA-256
131
133
  * ES384 - ECDSA using P-384 and SHA-384
132
134
  * ES512 - ECDSA using P-521 and SHA-512
135
+ * ES256K - ECDSA using P-256K and SHA-256
133
136
 
134
137
  ```ruby
135
- ecdsa_key = OpenSSL::PKey::EC.new 'prime256v1'
136
- ecdsa_key.generate_key
137
- ecdsa_public = OpenSSL::PKey::EC.new ecdsa_key
138
- ecdsa_public.private_key = nil
138
+ ecdsa_key = OpenSSL::PKey::EC.generate('prime256v1')
139
139
 
140
140
  token = JWT.encode payload, ecdsa_key, 'ES256'
141
141
 
142
142
  # eyJhbGciOiJFUzI1NiJ9.eyJkYXRhIjoidGVzdCJ9.AlLW--kaF7EX1NMX9WJRuIW8NeRJbn2BLXHns7Q5TZr7Hy3lF6MOpMlp7GoxBFRLISQ6KrD0CJOrR8aogEsPeg
143
143
  puts token
144
144
 
145
- decoded_token = JWT.decode token, ecdsa_public, true, { algorithm: 'ES256' }
145
+ decoded_token = JWT.decode token, ecdsa_key, true, { algorithm: 'ES256' }
146
146
 
147
147
  # Array
148
148
  # [
@@ -183,7 +183,7 @@ decoded_token = JWT.decode token, public_key, true, { algorithm: 'ED25519' }
183
183
 
184
184
  ### **RSASSA-PSS**
185
185
 
186
- In order to use this algorithm you need to add the `openssl` gem to you `Gemfile` with a version greater or equal to `2.1`.
186
+ In order to use this algorithm you need to add the `openssl` gem to your `Gemfile` with a version greater or equal to `2.1`.
187
187
 
188
188
  ```ruby
189
189
  gem 'openssl', '~> 2.1'
@@ -543,30 +543,41 @@ end
543
543
 
544
544
  ### JSON Web Key (JWK)
545
545
 
546
- JWK is a JSON structure representing a cryptographic key. Currently only supports RSA, EC and HMAC keys.
546
+ JWK is a JSON structure representing a cryptographic key. Currently only supports RSA, EC and HMAC keys. The `jwks` option can be given as a lambda that evaluates every time a kid is resolved.
547
547
 
548
- ```ruby
549
- jwk = JWT::JWK.new(OpenSSL::PKey::RSA.new(2048), "optional-kid")
550
- payload, headers = { data: 'data' }, { kid: jwk.kid }
548
+ If the kid is not found from the given set the loader will be called a second time with the `kid_not_found` option set to `true`. The application can choose to implement some kind of JWK cache invalidation or other mechanism to handle such cases.
551
549
 
552
- token = JWT.encode(payload, jwk.keypair, 'RS512', headers)
553
-
554
- # The jwk loader would fetch the set of JWKs from a trusted source
555
- jwk_loader = ->(options) do
556
- @cached_keys = nil if options[:invalidate] # need to reload the keys
557
- @cached_keys ||= { keys: [jwk.export] }
558
- end
550
+ ```ruby
551
+ jwk = JWT::JWK.new(OpenSSL::PKey::RSA.new(2048), 'optional-kid')
552
+ payload = { data: 'data' }
553
+ headers = { kid: jwk.kid }
554
+
555
+ token = JWT.encode(payload, jwk.keypair, 'RS512', headers)
556
+
557
+ # The jwk loader would fetch the set of JWKs from a trusted source,
558
+ # to avoid malicious requests triggering cache invalidations there needs to be some kind of grace time or other logic for determining the validity of the invalidation.
559
+ # This example only allows cache invalidations every 5 minutes.
560
+ jwk_loader = ->(options) do
561
+ if options[:kid_not_found] && @cache_last_update < Time.now.to_i - 300
562
+ logger.info("Invalidating JWK cache. #{options[:kid]} not found from previous cache")
563
+ @cached_keys = nil
564
+ end
565
+ @cached_keys ||= begin
566
+ @cache_last_update = Time.now.to_i
567
+ { keys: [jwk.export] }
568
+ end
569
+ end
559
570
 
560
- begin
561
- JWT.decode(token, nil, true, { algorithms: ['RS512'], jwks: jwk_loader})
562
- rescue JWT::JWKError
563
- # Handle problems with the provided JWKs
564
- rescue JWT::DecodeError
565
- # Handle other decode related issues e.g. no kid in header, no matching public key found etc.
566
- end
571
+ begin
572
+ JWT.decode(token, nil, true, { algorithms: ['RS512'], jwks: jwk_loader })
573
+ rescue JWT::JWKError
574
+ # Handle problems with the provided JWKs
575
+ rescue JWT::DecodeError
576
+ # Handle other decode related issues e.g. no kid in header, no matching public key found etc.
577
+ end
567
578
  ```
568
579
 
569
- or by passing JWK as a simple Hash
580
+ or by passing the JWKs as a simple Hash
570
581
 
571
582
  ```
572
583
  jwks = { keys: [{ ... }] } # keys accepts both of string and symbol
@@ -575,7 +586,7 @@ JWT.decode(token, nil, true, { algorithms: ['RS512'], jwks: jwks})
575
586
 
576
587
  ### Importing and exporting JSON Web Keys
577
588
 
578
- The ::JWT::JWK class can be used to import and export both the public key (default behaviour) and the private key. To include the private key in the export pass the `include_private` parameter to the export method.
589
+ The ::JWT::JWK class can be used to import and export both the public key (default behaviour) and the private key. To include the private key in the export pass the `include_private` parameter to the export method.
579
590
 
580
591
  ```ruby
581
592
  jwk = JWT::JWK.new(OpenSSL::PKey::RSA.new(2048))
@@ -584,6 +595,23 @@ jwk_hash = jwk.export
584
595
  jwk_hash_with_private_key = jwk.export(include_private: true)
585
596
  ```
586
597
 
598
+ ### Key ID (kid) and JWKs
599
+
600
+ The key id (kid) generation in the gem is a custom algorithm and not based on any standards. To use a standardized JWK thumbprint (RFC 7638) as the kid for JWKs a generator type can be specified in the global configuration or can be given to the JWK instance on initialization.
601
+
602
+ ```ruby
603
+ JWT.configuration.jwk.kid_generator_type = :rfc7638_thumbprint
604
+ # OR
605
+ JWT.configuration.jwk.kid_generator = ::JWT::JWK::Thumbprint
606
+ # OR
607
+ jwk = JWT::JWK.new(OpenSSL::PKey::RSA.new(2048), kid_generator: ::JWT::JWK::Thumbprint)
608
+
609
+ jwk_hash = jwk.export
610
+
611
+ thumbprint_as_the_kid = jwk_hash[:kid]
612
+
613
+ ```
614
+
587
615
  # Development and Tests
588
616
 
589
617
  We depend on [Bundler](http://rubygems.org/gems/bundler) for defining gemspec and performing releases to rubygems.org, which can be done with
@@ -599,12 +627,13 @@ bundle install
599
627
  bundle exec appraisal rake test
600
628
  ```
601
629
 
602
- **If you want a release cut with your PR, please include a version bump according to [Semantic Versioning](http://semver.org/)**
630
+ ## How to contribute
631
+ See [CONTRIBUTING](CONTRIBUTING.md).
603
632
 
604
633
  ## Contributors
605
634
 
606
- See `AUTHORS` file.
635
+ See [AUTHORS](AUTHORS).
607
636
 
608
637
  ## License
609
638
 
610
- See `LICENSE` file.
639
+ See [LICENSE](LICENSE).
@@ -6,13 +6,29 @@ module JWT
6
6
  module_function
7
7
 
8
8
  NAMED_CURVES = {
9
- 'prime256v1' => 'ES256',
10
- 'secp256r1' => 'ES256', # alias for prime256v1
11
- 'secp384r1' => 'ES384',
12
- 'secp521r1' => 'ES512'
9
+ 'prime256v1' => {
10
+ algorithm: 'ES256',
11
+ digest: 'sha256'
12
+ },
13
+ 'secp256r1' => { # alias for prime256v1
14
+ algorithm: 'ES256',
15
+ digest: 'sha256'
16
+ },
17
+ 'secp384r1' => {
18
+ algorithm: 'ES384',
19
+ digest: 'sha384'
20
+ },
21
+ 'secp521r1' => {
22
+ algorithm: 'ES512',
23
+ digest: 'sha512'
24
+ },
25
+ 'secp256k1' => {
26
+ algorithm: 'ES256K',
27
+ digest: 'sha256'
28
+ }
13
29
  }.freeze
14
30
 
15
- SUPPORTED = NAMED_CURVES.values.uniq.freeze
31
+ SUPPORTED = NAMED_CURVES.map { |_, c| c[:algorithm] }.uniq.freeze
16
32
 
17
33
  def sign(to_sign)
18
34
  algorithm, msg, key = to_sign.values
@@ -39,14 +55,9 @@ module JWT
39
55
  end
40
56
 
41
57
  def curve_by_name(name)
42
- algorithm = NAMED_CURVES.fetch(name) do
58
+ NAMED_CURVES.fetch(name) do
43
59
  raise UnsupportedEcdsaCurve, "The ECDSA curve '#{name}' is not supported"
44
60
  end
45
-
46
- {
47
- algorithm: algorithm,
48
- digest: algorithm.sub('ES', 'sha')
49
- }
50
61
  end
51
62
  end
52
63
  end
@@ -27,6 +27,8 @@ module JWT
27
27
  raise DecodeError, "key given is a #{public_key.class} but has to be a RbNaCl::Signatures::Ed25519::VerifyKey" if public_key.class != RbNaCl::Signatures::Ed25519::VerifyKey
28
28
 
29
29
  public_key.verify(signature, signing_input)
30
+ rescue RbNaCl::CryptoError
31
+ false
30
32
  end
31
33
  end
32
34
  end
data/lib/jwt/base64.rb ADDED
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+
5
+ module JWT
6
+ # Base64 helpers
7
+ class Base64
8
+ class << self
9
+ def url_encode(str)
10
+ ::Base64.encode64(str).tr('+/', '-_').gsub(/[\n=]/, '')
11
+ end
12
+
13
+ def url_decode(str)
14
+ str += '=' * (4 - str.length.modulo(4))
15
+ ::Base64.decode64(str.tr('-_', '+/'))
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'decode_configuration'
4
+ require_relative 'jwk_configuration'
5
+
6
+ module JWT
7
+ module Configuration
8
+ class Container
9
+ attr_accessor :decode, :jwk
10
+
11
+ def initialize
12
+ reset!
13
+ end
14
+
15
+ def reset!
16
+ @decode = DecodeConfiguration.new
17
+ @jwk = JwkConfiguration.new
18
+ end
19
+ end
20
+ end
21
+ end