Skip to content

Commit caebfff

Browse files
authored
chore(deps): Updated jwt and go-jose (#50)
* chore(deps): Updated jwt and go-jose * chore: Ran go mod tidy
1 parent 6186c30 commit caebfff

12 files changed

+88
-95
lines changed

encryption.go

+5-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import (
1010
"encoding/json"
1111
"errors"
1212
"fmt"
13+
"time"
14+
1315
"github.com/go-jose/go-jose/v3"
14-
"github.com/golang-jwt/jwt"
16+
"github.com/golang-jwt/jwt/v5"
1517
)
1618

1719
const (
@@ -151,7 +153,7 @@ func (k *Keypair) SignJWT(claims jwt.Claims) (string, error) {
151153
}
152154

153155
// VerifyJWT verifies the signature of a token was signed with this Keypair
154-
func (k *Keypair) VerifyJWT(token string) (*jwt.Token, error) {
156+
func (k *Keypair) VerifyJWT(token string, nowFunc func() time.Time) (*jwt.Token, error) {
155157
return jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
156158
kid, err := k.KeyID()
157159
if err != nil {
@@ -161,7 +163,7 @@ func (k *Keypair) VerifyJWT(token string) (*jwt.Token, error) {
161163
return k.PublicKey, nil
162164
}
163165
return nil, errors.New("token kid does not match or is not present")
164-
})
166+
}, jwt.WithTimeFunc(nowFunc))
165167
}
166168

167169
func randomNonce(length int) (string, error) {

encryption_test.go

+17-14
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,26 @@ import (
77
"testing"
88
"time"
99

10-
"github.com/golang-jwt/jwt"
10+
"github.com/golang-jwt/jwt/v5"
1111
"github.com/oauth2-proxy/mockoidc"
1212
"github.com/stretchr/testify/assert"
1313
)
1414

15+
var audience = jwt.ClaimStrings{"mockoidc"}
16+
1517
const (
16-
audience = "mockoidc"
1718
issuer = "https://github.com/oauth2-proxy/mockoidc/"
1819
defaultKid = "dHXTSCyouq6DiWaQwlXtNP54-C75mw3IcoYkERfl3fQ"
1920
)
2021

2122
var (
22-
standardClaims = &jwt.StandardClaims{
23+
registeredClaims = &jwt.RegisteredClaims{
2324
Audience: audience,
24-
ExpiresAt: time.Now().Add(time.Duration(1) * time.Hour).Unix(),
25-
Id: "0123456789abcdef",
26-
IssuedAt: time.Now().Unix(),
25+
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(1) * time.Hour)),
26+
ID: "0123456789abcdef",
27+
IssuedAt: jwt.NewNumericDate(time.Now()),
2728
Issuer: issuer,
28-
NotBefore: 0,
29+
NotBefore: jwt.NewNumericDate(time.Time{}),
2930
Subject: "123456789",
3031
}
3132
)
@@ -60,31 +61,33 @@ func TestKeypair_SignJWTVerifyJWT(t *testing.T) {
6061

6162
assert.NotEqual(t, alice.PrivateKey.N, bob.PrivateKey.N)
6263

63-
tokenStr, err := alice.SignJWT(standardClaims)
64+
tokenStr, err := alice.SignJWT(registeredClaims)
6465
assert.NoError(t, err)
6566

66-
_, err = bob.VerifyJWT(tokenStr)
67+
_, err = bob.VerifyJWT(tokenStr, mockoidc.NowFunc)
6768
assert.Error(t, err)
6869

69-
token, err := alice.VerifyJWT(tokenStr)
70+
token, err := alice.VerifyJWT(tokenStr, mockoidc.NowFunc)
7071
assert.NoError(t, err)
7172
assert.True(t, token.Valid)
7273

7374
claims, ok := token.Claims.(jwt.MapClaims)
7475
assert.True(t, ok)
75-
assert.Equal(t, audience, claims["aud"])
76+
claimAudience, err := claims.GetAudience()
77+
assert.NoError(t, err)
78+
assert.Equal(t, audience, claimAudience)
7679
assert.Equal(t, issuer, claims["iss"])
7780

7881
alice.Kid = "WRONG"
79-
_, err = alice.VerifyJWT(tokenStr)
82+
_, err = alice.VerifyJWT(tokenStr, mockoidc.NowFunc)
8083
assert.Error(t, err)
8184

8285
const customKid = "USER_DEFINED"
8386
bob.Kid = customKid
84-
kidTokenStr, err := bob.SignJWT(standardClaims)
87+
kidTokenStr, err := bob.SignJWT(registeredClaims)
8588
assert.NoError(t, err)
8689

87-
kidToken, err := bob.VerifyJWT(kidTokenStr)
90+
kidToken, err := bob.VerifyJWT(kidTokenStr, mockoidc.NowFunc)
8891
assert.NoError(t, err)
8992
assert.Equal(t, customKid, kidToken.Header["kid"])
9093
})

go.mod

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
module github.com/oauth2-proxy/mockoidc
22

3-
go 1.16
3+
go 1.21
44

55
require (
66
github.com/go-jose/go-jose/v3 v3.0.1
7-
github.com/golang-jwt/jwt v3.2.2+incompatible
8-
github.com/google/go-cmp v0.5.4 // indirect
9-
github.com/stretchr/testify v1.7.0
7+
github.com/golang-jwt/jwt/v5 v5.2.0
8+
github.com/stretchr/testify v1.8.4
9+
)
10+
11+
require (
12+
github.com/davecgh/go-spew v1.1.1 // indirect
13+
github.com/google/go-cmp v0.6.0 // indirect
14+
github.com/pmezard/go-difflib v1.0.0 // indirect
1015
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect
16+
gopkg.in/yaml.v3 v3.0.1 // indirect
1117
)

go.sum

+10-15
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,30 @@
1-
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
21
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
2+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
3+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
34
github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA=
45
github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8=
5-
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
6-
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
6+
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
7+
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
78
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
8-
github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M=
9-
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
9+
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
10+
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
1011
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1112
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1213
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
1314
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
14-
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
15-
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
15+
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
16+
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
1617
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
1718
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
1819
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
1920
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
2021
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
21-
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
2222
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
2323
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
24-
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
25-
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
26-
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
27-
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
2824
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
29-
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
30-
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
3125
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
3226
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
3327
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
34-
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
3528
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
29+
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
30+
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

handlers.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import (
99
"strings"
1010
"time"
1111

12-
"github.com/golang-jwt/jwt"
12+
"github.com/golang-jwt/jwt/v5"
1313
)
1414

1515
const (
@@ -403,7 +403,7 @@ func (m *MockOIDC) authorizeBearer(rw http.ResponseWriter, req *http.Request) (*
403403
}
404404

405405
func (m *MockOIDC) authorizeToken(t string, rw http.ResponseWriter) (*jwt.Token, bool) {
406-
token, err := m.Keypair.VerifyJWT(t)
406+
token, err := m.Keypair.VerifyJWT(t, m.Now)
407407
if err != nil {
408408
errorResponse(rw, InvalidRequest, fmt.Sprintf("Invalid token: %v", err), http.StatusUnauthorized)
409409
return nil, false

handlers_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func TestMockOIDC_Token_CodeGrant(t *testing.T) {
133133
"id_token",
134134
} {
135135
t.Run(key, func(t *testing.T) {
136-
_, err := m.Keypair.VerifyJWT(tokenResp[key].(string))
136+
_, err := m.Keypair.VerifyJWT(tokenResp[key].(string), m.Now)
137137
assert.NoError(t, err)
138138
})
139139
}
@@ -279,7 +279,7 @@ func TestMockOIDC_Token_RefreshGrant(t *testing.T) {
279279
"id_token",
280280
} {
281281
t.Run(key, func(t *testing.T) {
282-
_, err := m.Keypair.VerifyJWT(tokenResp[key].(string))
282+
_, err := m.Keypair.VerifyJWT(tokenResp[key].(string), m.Now)
283283
assert.NoError(t, err)
284284
})
285285
}

mockoidc.go

-15
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ import (
99
"net"
1010
"net/http"
1111
"time"
12-
13-
"github.com/golang-jwt/jwt"
1412
)
1513

1614
// NowFunc is an overrideable version of `time.Now`. Tests that need to
@@ -195,19 +193,6 @@ func (m *MockOIDC) Now() time.Time {
195193
return NowFunc().Add(m.fastForward)
196194
}
197195

198-
// TimeReset is a function that resets time
199-
type TimeReset func()
200-
201-
// Synchronize sets the jwt.TimeFunc to our mutated view of time.
202-
// It returns a func that can reset it to its original state.
203-
func (m *MockOIDC) Synchronize() TimeReset {
204-
original := jwt.TimeFunc
205-
206-
jwt.TimeFunc = m.Now
207-
208-
return func() { jwt.TimeFunc = original }
209-
}
210-
211196
// Addr returns the server address (if started)
212197
func (m *MockOIDC) Addr() string {
213198
if m.Server == nil {

mockoidc_test.go

+10-14
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import (
1111
"testing"
1212
"time"
1313

14-
"github.com/golang-jwt/jwt"
14+
"github.com/golang-jwt/jwt/v5"
1515
"github.com/oauth2-proxy/mockoidc"
1616
"github.com/stretchr/testify/assert"
1717
)
@@ -33,10 +33,6 @@ func TestRun(t *testing.T) {
3333
assert.NoError(t, err)
3434
defer m.Shutdown()
3535

36-
// Override jwt.TimeFunc with our timer
37-
reset := m.Synchronize()
38-
defer reset()
39-
4036
// ************************************************************************
4137
// Stage 0: Get Discovery documents
4238
// ************************************************************************
@@ -122,11 +118,11 @@ func TestRun(t *testing.T) {
122118
err = json.Unmarshal(body, &tokens)
123119
assert.NoError(t, err)
124120

125-
_, err = m.Keypair.VerifyJWT(tokens["access_token"].(string))
121+
_, err = m.Keypair.VerifyJWT(tokens["access_token"].(string), m.Now)
126122
assert.NoError(t, err)
127-
_, err = m.Keypair.VerifyJWT(tokens["refresh_token"].(string))
123+
_, err = m.Keypair.VerifyJWT(tokens["refresh_token"].(string), m.Now)
128124
assert.NoError(t, err)
129-
idToken, err := m.Keypair.VerifyJWT(tokens["id_token"].(string))
125+
idToken, err := m.Keypair.VerifyJWT(tokens["id_token"].(string), m.Now)
130126
assert.NoError(t, err)
131127

132128
// The nonce we set initially is in our ID Token
@@ -184,11 +180,11 @@ func TestRun(t *testing.T) {
184180
err = json.Unmarshal(refreshBody, &refreshedTokens)
185181
assert.NoError(t, err)
186182

187-
_, err = m.Keypair.VerifyJWT(refreshedTokens["access_token"].(string))
183+
_, err = m.Keypair.VerifyJWT(refreshedTokens["access_token"].(string), m.Now)
188184
assert.NoError(t, err)
189-
_, err = m.Keypair.VerifyJWT(refreshedTokens["refresh_token"].(string))
185+
_, err = m.Keypair.VerifyJWT(refreshedTokens["refresh_token"].(string), m.Now)
190186
assert.NoError(t, err)
191-
refreshedIDToken, err := m.Keypair.VerifyJWT(refreshedTokens["id_token"].(string))
187+
refreshedIDToken, err := m.Keypair.VerifyJWT(refreshedTokens["id_token"].(string), m.Now)
192188
assert.NoError(t, err)
193189

194190
// The nonce we set initially is STILL in our ID Token
@@ -366,12 +362,12 @@ func setTime() {
366362
mockoidc.NowFunc = func() time.Time {
367363
return time.Unix(TestNow, 0)
368364
}
369-
jwt.TimeFunc = func() time.Time {
365+
jwt.WithTimeFunc(func() time.Time {
370366
return time.Unix(TestNow, 0)
371-
}
367+
})
372368
}
373369

374370
func resetTime() {
375371
mockoidc.NowFunc = time.Now
376-
jwt.TimeFunc = time.Now
372+
jwt.WithTimeFunc(time.Now)
377373
}

session.go

+13-13
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
"strings"
66
"time"
77

8-
"github.com/golang-jwt/jwt"
8+
"github.com/golang-jwt/jwt/v5"
99
)
1010

1111
// Session stores a User and their OIDC options across requests
@@ -29,7 +29,7 @@ type SessionStore struct {
2929
// should use in their jwt.Claims building.
3030
type IDTokenClaims struct {
3131
Nonce string `json:"nonce,omitempty"`
32-
*jwt.StandardClaims
32+
*jwt.RegisteredClaims
3333
}
3434

3535
// NewSessionStore initializes the SessionStore for this server
@@ -84,23 +84,23 @@ func (ss *SessionStore) GetSessionByToken(token *jwt.Token) (*Session, error) {
8484
// AccessToken returns the JWT token with the appropriate claims for
8585
// an access token
8686
func (s *Session) AccessToken(config *Config, kp *Keypair, now time.Time) (string, error) {
87-
claims := s.standardClaims(config, config.AccessTTL, now)
87+
claims := s.registeredClaims(config, config.AccessTTL, now)
8888
return kp.SignJWT(claims)
8989
}
9090

9191
// RefreshToken returns the JWT token with the appropriate claims for
9292
// a refresh token
9393
func (s *Session) RefreshToken(config *Config, kp *Keypair, now time.Time) (string, error) {
94-
claims := s.standardClaims(config, config.RefreshTTL, now)
94+
claims := s.registeredClaims(config, config.RefreshTTL, now)
9595
return kp.SignJWT(claims)
9696
}
9797

9898
// IDToken returns the JWT token with the appropriate claims for a user
9999
// based on the scopes set.
100100
func (s *Session) IDToken(config *Config, kp *Keypair, now time.Time) (string, error) {
101101
base := &IDTokenClaims{
102-
StandardClaims: s.standardClaims(config, config.AccessTTL, now),
103-
Nonce: s.OIDCNonce,
102+
RegisteredClaims: s.registeredClaims(config, config.AccessTTL, now),
103+
Nonce: s.OIDCNonce,
104104
}
105105
claims, err := s.User.Claims(s.Scopes, base)
106106
if err != nil {
@@ -110,14 +110,14 @@ func (s *Session) IDToken(config *Config, kp *Keypair, now time.Time) (string, e
110110
return kp.SignJWT(claims)
111111
}
112112

113-
func (s *Session) standardClaims(config *Config, ttl time.Duration, now time.Time) *jwt.StandardClaims {
114-
return &jwt.StandardClaims{
115-
Audience: config.ClientID,
116-
ExpiresAt: now.Add(ttl).Unix(),
117-
Id: s.SessionID,
118-
IssuedAt: now.Unix(),
113+
func (s *Session) registeredClaims(config *Config, ttl time.Duration, now time.Time) *jwt.RegisteredClaims {
114+
return &jwt.RegisteredClaims{
115+
Audience: jwt.ClaimStrings{config.ClientID},
116+
ExpiresAt: jwt.NewNumericDate(now.Add(ttl)),
117+
ID: s.SessionID,
118+
IssuedAt: jwt.NewNumericDate(now),
119119
Issuer: config.Issuer,
120-
NotBefore: now.Unix(),
120+
NotBefore: jwt.NewNumericDate(now),
121121
Subject: s.User.ID(),
122122
}
123123
}

0 commit comments

Comments
 (0)