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 +4 -4
- data/.github/workflows/test.yml +15 -14
- data/.reek.yml +22 -0
- data/.rubocop.yml +9 -23
- data/.sourcelevel.yml +3 -4
- data/CHANGELOG.md +36 -37
- data/CONTRIBUTING.md +99 -0
- data/README.md +59 -30
- data/lib/jwt/algos/ecdsa.rb +22 -11
- data/lib/jwt/algos/eddsa.rb +2 -0
- data/lib/jwt/base64.rb +19 -0
- data/lib/jwt/configuration/container.rb +21 -0
- data/lib/jwt/configuration/decode_configuration.rb +46 -0
- data/lib/jwt/configuration/jwk_configuration.rb +27 -0
- data/lib/jwt/configuration.rb +15 -0
- data/lib/jwt/decode.rb +4 -4
- data/lib/jwt/encode.rb +2 -2
- data/lib/jwt/jwk/ec.rb +95 -46
- data/lib/jwt/jwk/hmac.rb +19 -10
- data/lib/jwt/jwk/key_base.rb +23 -7
- data/lib/jwt/jwk/key_finder.rb +1 -1
- data/lib/jwt/jwk/kid_as_key_digest.rb +15 -0
- data/lib/jwt/jwk/rsa.rb +54 -32
- data/lib/jwt/jwk/thumbprint.rb +26 -0
- data/lib/jwt/version.rb +7 -2
- data/lib/jwt/x5c_key_finder.rb +1 -1
- data/lib/jwt.rb +6 -5
- data/ruby-jwt.gemspec +2 -1
- metadata +29 -8
- data/.rubocop_todo.yml +0 -22
- data/lib/jwt/default_options.rb +0 -18
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a3098671a837e7b291103cde1921277c61ecaa0f0797b955e6adc65328498f0d
|
|
4
|
+
data.tar.gz: 3253833ac6d7743e40a5d5157b161cd0daecc9b77f61dfa7687d6b3da1be56ca
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 306c946b1199301a3f1000c8ffba4a77d07fd05dd83f769da86fd29f254827b5af8488a4b6a54b11f1f7f3a028cb88caafb7ed67528e7004c0337f6506e595ea
|
|
7
|
+
data.tar.gz: 57d1eba7a06bc9d9f9fcb76b42aa3808415af5020c53969b4cada890b1646e7d348a96ce18010ab0a978e42825febbeb7b3f205b72e8ce60ef90132cf5887599
|
data/.github/workflows/test.yml
CHANGED
|
@@ -13,43 +13,44 @@ jobs:
|
|
|
13
13
|
timeout-minutes: 30
|
|
14
14
|
runs-on: ubuntu-latest
|
|
15
15
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
16
|
+
- uses: actions/checkout@v3
|
|
17
17
|
- name: Set up Ruby
|
|
18
18
|
uses: ruby/setup-ruby@v1
|
|
19
19
|
with:
|
|
20
|
-
ruby-version: "
|
|
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
|
-
|
|
42
|
-
- ruby: "
|
|
43
|
-
|
|
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@
|
|
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:
|
|
32
|
+
Max: 112
|
|
41
33
|
|
|
42
34
|
Metrics/ModuleLength:
|
|
43
35
|
Max: 100
|
|
44
36
|
|
|
45
|
-
|
|
46
|
-
|
|
37
|
+
Metrics/MethodLength:
|
|
38
|
+
Max: 20
|
|
47
39
|
|
|
48
40
|
Metrics/BlockLength:
|
|
49
41
|
Exclude:
|
|
50
42
|
- spec/**/*_spec.rb
|
|
51
43
|
|
|
52
|
-
|
|
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
|
-
|
|
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:
|
|
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:
|
|
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
|
-
[
|
|
4
|
+
## [v2.5.0](https://github.com/jwt/ruby-jwt/tree/v2.5.0) (NEXT)
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
[Full Changelog](https://github.com/jwt/ruby-jwt/compare/v2.4.1...master)
|
|
8
7
|
|
|
9
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
21
|
+
## [v2.4.1](https://github.com/jwt/ruby-jwt/tree/v2.4.1) (2022-06-07)
|
|
18
22
|
|
|
19
|
-
|
|
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
|
-
**
|
|
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
|
-
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
-
|
|
32
|
-
-
|
|
33
|
-
-
|
|
34
|
-
-
|
|
35
|
-
-
|
|
36
|
-
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
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.
|
|
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,
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
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
|
-
|
|
562
|
-
rescue JWT::JWKError
|
|
563
|
-
|
|
564
|
-
rescue JWT::DecodeError
|
|
565
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
630
|
+
## How to contribute
|
|
631
|
+
See [CONTRIBUTING](CONTRIBUTING.md).
|
|
603
632
|
|
|
604
633
|
## Contributors
|
|
605
634
|
|
|
606
|
-
See
|
|
635
|
+
See [AUTHORS](AUTHORS).
|
|
607
636
|
|
|
608
637
|
## License
|
|
609
638
|
|
|
610
|
-
See
|
|
639
|
+
See [LICENSE](LICENSE).
|
data/lib/jwt/algos/ecdsa.rb
CHANGED
|
@@ -6,13 +6,29 @@ module JWT
|
|
|
6
6
|
module_function
|
|
7
7
|
|
|
8
8
|
NAMED_CURVES = {
|
|
9
|
-
'prime256v1' =>
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
data/lib/jwt/algos/eddsa.rb
CHANGED
|
@@ -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
|