jwt 2.4.0.beta1 → 2.5.0

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
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