Skip to content

Commit e7e27fe

Browse files
committed
Upgrade jwx to v3
1 parent 26e87e1 commit e7e27fe

File tree

4 files changed

+121
-68
lines changed

4 files changed

+121
-68
lines changed

go.mod

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ go 1.25
44

55
require (
66
github.com/caddyserver/caddy/v2 v2.10.2
7-
github.com/lestrrat-go/jwx/v2 v2.1.6
7+
github.com/lestrrat-go/httprc/v3 v3.0.2
8+
github.com/lestrrat-go/jwx/v3 v3.0.13
89
github.com/stretchr/testify v1.11.1
910
go.uber.org/zap v1.27.0
1011
)
@@ -64,10 +65,10 @@ require (
6465
github.com/klauspost/compress v1.18.1 // indirect
6566
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
6667
github.com/lestrrat-go/blackmagic v1.0.4 // indirect
68+
github.com/lestrrat-go/dsig v1.0.0 // indirect
69+
github.com/lestrrat-go/dsig-secp256k1 v1.0.0 // indirect
6770
github.com/lestrrat-go/httpcc v1.0.1 // indirect
68-
github.com/lestrrat-go/httprc v1.0.6 // indirect
69-
github.com/lestrrat-go/iter v1.0.2 // indirect
70-
github.com/lestrrat-go/option v1.0.1 // indirect
71+
github.com/lestrrat-go/option/v2 v2.0.0 // indirect
7172
github.com/libdns/libdns v1.1.1 // indirect
7273
github.com/manifoldco/promptui v0.9.0 // indirect
7374
github.com/mattn/go-colorable v0.1.14 // indirect
@@ -107,6 +108,7 @@ require (
107108
github.com/stoewer/go-strcase v1.3.1 // indirect
108109
github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53 // indirect
109110
github.com/urfave/cli v1.22.17 // indirect
111+
github.com/valyala/fastjson v1.6.7 // indirect
110112
github.com/zeebo/blake3 v0.2.4 // indirect
111113
go.etcd.io/bbolt v1.4.3 // indirect
112114
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
@@ -119,16 +121,16 @@ require (
119121
go.uber.org/multierr v1.11.0 // indirect
120122
go.uber.org/zap/exp v0.3.0 // indirect
121123
go.yaml.in/yaml/v2 v2.4.3 // indirect
122-
golang.org/x/crypto v0.44.0 // indirect
124+
golang.org/x/crypto v0.46.0 // indirect
123125
golang.org/x/crypto/x509roots/fallback v0.0.0-20251112184832-bcf6a849efcf // indirect
124126
golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 // indirect
125127
golang.org/x/mod v0.30.0 // indirect
126128
golang.org/x/net v0.47.0 // indirect
127129
golang.org/x/oauth2 v0.33.0 // indirect
128-
golang.org/x/sync v0.18.0 // indirect
129-
golang.org/x/sys v0.38.0 // indirect
130-
golang.org/x/term v0.37.0 // indirect
131-
golang.org/x/text v0.31.0 // indirect
130+
golang.org/x/sync v0.19.0 // indirect
131+
golang.org/x/sys v0.39.0 // indirect
132+
golang.org/x/term v0.38.0 // indirect
133+
golang.org/x/text v0.32.0 // indirect
132134
golang.org/x/time v0.14.0 // indirect
133135
golang.org/x/tools v0.39.0 // indirect
134136
google.golang.org/api v0.256.0 // indirect

go.sum

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -201,16 +201,18 @@ github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0
201201
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
202202
github.com/lestrrat-go/blackmagic v1.0.4 h1:IwQibdnf8l2KoO+qC3uT4OaTWsW7tuRQXy9TRN9QanA=
203203
github.com/lestrrat-go/blackmagic v1.0.4/go.mod h1:6AWFyKNNj0zEXQYfTMPfZrAXUWUfTIZ5ECEUEJaijtw=
204+
github.com/lestrrat-go/dsig v1.0.0 h1:OE09s2r9Z81kxzJYRn07TFM9XA4akrUdoMwr0L8xj38=
205+
github.com/lestrrat-go/dsig v1.0.0/go.mod h1:dEgoOYYEJvW6XGbLasr8TFcAxoWrKlbQvmJgCR0qkDo=
206+
github.com/lestrrat-go/dsig-secp256k1 v1.0.0 h1:JpDe4Aybfl0soBvoVwjqDbp+9S1Y2OM7gcrVVMFPOzY=
207+
github.com/lestrrat-go/dsig-secp256k1 v1.0.0/go.mod h1:CxUgAhssb8FToqbL8NjSPoGQlnO4w3LG1P0qPWQm/NU=
204208
github.com/lestrrat-go/httpcc v1.0.1 h1:ydWCStUeJLkpYyjLDHihupbn2tYmZ7m22BGkcvZZrIE=
205209
github.com/lestrrat-go/httpcc v1.0.1/go.mod h1:qiltp3Mt56+55GPVCbTdM9MlqhvzyuL6W/NMDA8vA5E=
206-
github.com/lestrrat-go/httprc v1.0.6 h1:qgmgIRhpvBqexMJjA/PmwSvhNk679oqD1RbovdCGW8k=
207-
github.com/lestrrat-go/httprc v1.0.6/go.mod h1:mwwz3JMTPBjHUkkDv/IGJ39aALInZLrhBp0X7KGUZlo=
208-
github.com/lestrrat-go/iter v1.0.2 h1:gMXo1q4c2pHmC3dn8LzRhJfP1ceCbgSiT9lUydIzltI=
209-
github.com/lestrrat-go/iter v1.0.2/go.mod h1:Momfcq3AnRlRjI5b5O8/G5/BvpzrhoFTZcn06fEOPt4=
210-
github.com/lestrrat-go/jwx/v2 v2.1.6 h1:hxM1gfDILk/l5ylers6BX/Eq1m/pnxe9NBwW6lVfecA=
211-
github.com/lestrrat-go/jwx/v2 v2.1.6/go.mod h1:Y722kU5r/8mV7fYDifjug0r8FK8mZdw0K0GpJw/l8pU=
212-
github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU=
213-
github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I=
210+
github.com/lestrrat-go/httprc/v3 v3.0.2 h1:7u4HUaD0NQbf2/n5+fyp+T10hNCsAnwKfqn4A4Baif0=
211+
github.com/lestrrat-go/httprc/v3 v3.0.2/go.mod h1:mSMtkZW92Z98M5YoNNztbRGxbXHql7tSitCvaxvo9l0=
212+
github.com/lestrrat-go/jwx/v3 v3.0.13 h1:AdHKiPIYeCSnOJtvdpipPg/0SuFh9rdkN+HF3O0VdSk=
213+
github.com/lestrrat-go/jwx/v3 v3.0.13/go.mod h1:2m0PV1A9tM4b/jVLMx8rh6rBl7F6WGb3EG2hufN9OQU=
214+
github.com/lestrrat-go/option/v2 v2.0.0 h1:XxrcaJESE1fokHy3FpaQ/cXW8ZsIdWcdFzzLOcID3Ss=
215+
github.com/lestrrat-go/option/v2 v2.0.0/go.mod h1:oSySsmzMoR0iRzCDCaUfsCzxQHUEuhOViQObyy7S6Vg=
214216
github.com/libdns/libdns v1.1.1 h1:wPrHrXILoSHKWJKGd0EiAVmiJbFShguILTg9leS/P/U=
215217
github.com/libdns/libdns v1.1.1/go.mod h1:4Bj9+5CQiNMVGf87wjX4CY3HQJypUHRuLvlsfsZqLWQ=
216218
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
@@ -323,7 +325,6 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/
323325
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
324326
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
325327
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
326-
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
327328
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
328329
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
329330
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
@@ -337,6 +338,8 @@ github.com/tailscale/tscert v0.0.0-20240608151842-d3f834017e53/go.mod h1:kNGUQ3V
337338
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
338339
github.com/urfave/cli v1.22.17 h1:SYzXoiPfQjHBbkYxbew5prZHS1TOLT3ierW8SYLqtVQ=
339340
github.com/urfave/cli v1.22.17/go.mod h1:b0ht0aqgH/6pBYzzxURyrM4xXNgsoT/n2ZzwQiEhNVo=
341+
github.com/valyala/fastjson v1.6.7 h1:ZE4tRy0CIkh+qDc5McjatheGX2czdn8slQjomexVpBM=
342+
github.com/valyala/fastjson v1.6.7/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY=
340343
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
341344
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
342345
github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
@@ -386,8 +389,8 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY
386389
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
387390
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
388391
golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M=
389-
golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU=
390-
golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc=
392+
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
393+
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
391394
golang.org/x/crypto/x509roots/fallback v0.0.0-20251112184832-bcf6a849efcf h1:TQU3D+jWvAEg5cTSPjVvbWOI2LrriOfC2mXy7rO5rNQ=
392395
golang.org/x/crypto/x509roots/fallback v0.0.0-20251112184832-bcf6a849efcf/go.mod h1:MEIPiCnxvQEjA4astfaKItNwEVZA5Ki+3+nyGbJ5N18=
393396
golang.org/x/exp v0.0.0-20251113190631-e25ba8c21ef6 h1:zfMcR1Cs4KNuomFFgGefv5N0czO2XZpUbxGUy8i8ug0=
@@ -418,8 +421,8 @@ golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
418421
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
419422
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
420423
golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
421-
golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I=
422-
golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
424+
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
425+
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
423426
golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
424427
golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
425428
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -437,8 +440,8 @@ golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
437440
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
438441
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
439442
golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
440-
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
441-
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
443+
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
444+
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
442445
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
443446
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
444447
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -448,8 +451,8 @@ golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
448451
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
449452
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
450453
golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s=
451-
golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU=
452-
golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254=
454+
golang.org/x/term v0.38.0 h1:PQ5pkm/rLO6HnxFR7N2lJHOZX6Kez5Y1gDSJla6jo7Q=
455+
golang.org/x/term v0.38.0/go.mod h1:bSEAKrOT1W+VSu9TSCMtoGEOUcKxOKgl3LE5QEF/xVg=
453456
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
454457
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
455458
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
@@ -459,8 +462,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
459462
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
460463
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
461464
golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY=
462-
golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM=
463-
golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM=
465+
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
466+
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
464467
golang.org/x/time v0.14.0 h1:MRx4UaLrDotUKUdCIqzPC48t1Y9hANFKIRpNx+Te8PI=
465468
golang.org/x/time v0.14.0/go.mod h1:eL/Oa2bBBK0TkX57Fyni+NgnyQQN4LitPmob2Hjnqw4=
466469
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

jwt.go

Lines changed: 77 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@ import (
1717

1818
"github.com/caddyserver/caddy/v2"
1919
"github.com/caddyserver/caddy/v2/modules/caddyhttp/caddyauth"
20-
"github.com/lestrrat-go/jwx/v2/jwa"
21-
"github.com/lestrrat-go/jwx/v2/jwk"
22-
"github.com/lestrrat-go/jwx/v2/jws"
23-
"github.com/lestrrat-go/jwx/v2/jwt"
20+
"github.com/lestrrat-go/httprc/v3"
21+
"github.com/lestrrat-go/httprc/v3/errsink"
22+
"github.com/lestrrat-go/jwx/v3/jwa"
23+
"github.com/lestrrat-go/jwx/v3/jwk"
24+
"github.com/lestrrat-go/jwx/v3/jws"
25+
"github.com/lestrrat-go/jwx/v3/jwt"
2426
"go.uber.org/zap"
2527
)
2628

@@ -232,17 +234,28 @@ func (ja *JWTAuth) getOrCreateJWKCache(resolvedURL string) (*jwkCacheEntry, erro
232234
}
233235

234236
// Create a new cache for this URL
235-
cache := jwk.NewCache(context.Background(), jwk.WithErrSink(ja))
236-
err := cache.Register(resolvedURL)
237+
client := httprc.NewClient(httprc.WithErrorSink(errsink.NewFunc(func(_ context.Context, err error) {
238+
ja.Error(err)
239+
})))
240+
cache, err := jwk.NewCache(context.Background(), client)
241+
if err != nil {
242+
return nil, fmt.Errorf("failed to create JWK cache: %w", err)
243+
}
244+
err = cache.Register(context.Background(), resolvedURL)
237245
if err != nil {
238246
return nil, fmt.Errorf("failed to register JWK URL: %w", err)
239247
}
240248

249+
cachedSet, err := cache.CachedSet(resolvedURL)
250+
if err != nil {
251+
return nil, fmt.Errorf("failed to create cached JWK set: %w", err)
252+
}
253+
241254
// Create cache entry before attempting refresh
242255
entry = &jwkCacheEntry{
243256
URL: resolvedURL,
244257
Cache: cache,
245-
CachedSet: jwk.NewCachedSet(cache, resolvedURL),
258+
CachedSet: cachedSet,
246259
}
247260

248261
// Try to refresh the cache immediately
@@ -298,9 +311,8 @@ func (ja *JWTAuth) validateSignatureKeys() error {
298311
}
299312

300313
if ja.SignAlgorithm != "" {
301-
var alg jwa.SignatureAlgorithm
302-
if err := alg.Accept(ja.SignAlgorithm); err != nil {
303-
return fmt.Errorf("%w: %v", ErrInvalidSignAlgorithm, err)
314+
if _, ok := jwa.LookupSignatureAlgorithm(ja.SignAlgorithm); !ok {
315+
return fmt.Errorf("%w: %s", ErrInvalidSignAlgorithm, ja.SignAlgorithm)
304316
}
305317
}
306318
}
@@ -329,7 +341,7 @@ func (ja *JWTAuth) keyProvider(request *http.Request) jws.KeyProviderFunc {
329341
}
330342

331343
// Use the key set associated with this URL
332-
kid := sig.ProtectedHeaders().KeyID()
344+
kid, _ := sig.ProtectedHeaders().KeyID()
333345
key, found := cacheEntry.CachedSet.LookupKeyID(kid)
334346
if !found {
335347
// Trigger an asynchronous refresh if the key is not found
@@ -340,29 +352,41 @@ func (ja *JWTAuth) keyProvider(request *http.Request) jws.KeyProviderFunc {
340352
}
341353
return fmt.Errorf("key specified by kid %q not found in JWKs from %s", kid, resolvedURL)
342354
}
343-
sink.Key(ja.determineSigningAlgorithm(key.Algorithm(), sig.ProtectedHeaders().Algorithm()), key)
344-
} else if ja.SignAlgorithm == string(jwa.EdDSA) {
355+
keyAlg, keyAlgOk := key.Algorithm()
356+
headerAlg, headerAlgOk := sig.ProtectedHeaders().Algorithm()
357+
sink.Key(ja.determineSigningAlgorithm(keyAlg, keyAlgOk, headerAlg, headerAlgOk), key)
358+
} else if ja.SignAlgorithm == jwa.EdDSA().String() {
345359
if signKey, ok := ja.parsedSignKey.([]byte); !ok {
346360
return fmt.Errorf("EdDSA key must be base64 encoded bytes")
347361
} else if len(signKey) != ed25519.PublicKeySize {
348362
return fmt.Errorf("key is not a proper ed25519 length")
349363
} else {
350-
sink.Key(jwa.EdDSA, ed25519.PublicKey(signKey))
364+
sink.Key(jwa.EdDSA(), ed25519.PublicKey(signKey))
351365
}
352366
} else {
353-
sink.Key(ja.determineSigningAlgorithm(sig.ProtectedHeaders().Algorithm()), ja.parsedSignKey)
367+
headerAlg, headerAlgOk := sig.ProtectedHeaders().Algorithm()
368+
sink.Key(ja.determineSigningAlgorithm(nil, false, headerAlg, headerAlgOk), ja.parsedSignKey)
354369
}
355370
return nil
356371
}
357372
}
358373

359-
func (ja *JWTAuth) determineSigningAlgorithm(alg ...jwa.KeyAlgorithm) jwa.SignatureAlgorithm {
360-
for _, a := range alg {
361-
if a.String() != "" {
362-
return jwa.SignatureAlgorithm(a.String())
374+
func (ja *JWTAuth) determineSigningAlgorithm(keyAlg jwa.KeyAlgorithm, keyAlgOk bool, headerAlg jwa.SignatureAlgorithm, headerAlgOk bool) jwa.SignatureAlgorithm {
375+
if keyAlgOk {
376+
if alg, ok := jwa.LookupSignatureAlgorithm(keyAlg.String()); ok {
377+
return alg
363378
}
364379
}
365-
return jwa.SignatureAlgorithm(ja.SignAlgorithm) // can be ""
380+
if headerAlgOk && headerAlg.String() != "" {
381+
return headerAlg
382+
}
383+
if ja.SignAlgorithm == "" {
384+
return jwa.EmptySignatureAlgorithm()
385+
}
386+
if alg, ok := jwa.LookupSignatureAlgorithm(ja.SignAlgorithm); ok {
387+
return alg
388+
}
389+
return jwa.EmptySignatureAlgorithm()
366390
}
367391

368392
// Authenticate validates the JWT in the request and returns the user, if valid.
@@ -499,13 +523,17 @@ func getTokensFromCookies(r *http.Request, names []string) []string {
499523

500524
func getUserID(token Token, names []string) (string, string) {
501525
for _, name := range names {
502-
if userClaim, ok := token.Get(name); ok {
503-
switch val := userClaim.(type) {
504-
case string:
505-
return name, val
506-
case float64:
507-
return name, strconv.FormatFloat(val, 'f', -1, 64)
508-
}
526+
userClaim, ok := getTokenClaim(token, name)
527+
if !ok {
528+
continue
529+
}
530+
switch val := userClaim.(type) {
531+
case string:
532+
return name, val
533+
case float64:
534+
return name, strconv.FormatFloat(val, 'f', -1, 64)
535+
case json.Number:
536+
return name, val.String()
509537
}
510538
}
511539
return "", ""
@@ -531,10 +559,10 @@ func getUserMetadata(token Token, placeholdersMap map[string]string) map[string]
531559
return nil
532560
}
533561

534-
claims, _ := token.AsMap(context.Background()) // error ignored
562+
claims := tokenAsMap(token)
535563
metadata := make(map[string]string)
536564
for claim, placeholder := range placeholdersMap {
537-
claimValue, ok := token.Get(claim)
565+
claimValue, ok := getTokenClaim(token, claim)
538566

539567
// Query nested claims.
540568
if !ok && strings.Contains(claim, ".") {
@@ -550,6 +578,26 @@ func getUserMetadata(token Token, placeholdersMap map[string]string) map[string]
550578
return metadata
551579
}
552580

581+
func getTokenClaim(token Token, name string) (interface{}, bool) {
582+
var value interface{}
583+
if err := token.Get(name, &value); err != nil {
584+
return nil, false
585+
}
586+
return value, true
587+
}
588+
589+
func tokenAsMap(token Token) map[string]interface{} {
590+
claims := make(map[string]interface{})
591+
for _, key := range token.Keys() {
592+
value, ok := getTokenClaim(token, key)
593+
if !ok {
594+
continue
595+
}
596+
claims[key] = value
597+
}
598+
return claims
599+
}
600+
553601
func stringify(val interface{}) string {
554602
if val == nil {
555603
return ""

0 commit comments

Comments
 (0)