Skip to content

Commit 27e502e

Browse files
committed
Upgrade to go-jwt v5.
A token with no "sub" field is now treated just like one with an empty "sub". In addition, all times are treated with a slack of 5s.
1 parent 002d519 commit 27e502e

File tree

4 files changed

+40
-40
lines changed

4 files changed

+40
-40
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.19
44

55
require (
66
github.com/at-wat/ebml-go v0.17.0
7-
github.com/golang-jwt/jwt/v4 v4.5.0
7+
github.com/golang-jwt/jwt/v5 v5.2.0
88
github.com/gorilla/websocket v1.5.0
99
github.com/jech/cert v0.0.0-20210819231831-aca735647728
1010
github.com/jech/samplebuilder v0.0.0-20221109182433-6cbba09fc1c9

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
66
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
77
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
88
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE=
9-
github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
10-
github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
9+
github.com/golang-jwt/jwt/v5 v5.2.0 h1:d/ix8ftRUorsN+5eMIlF4T6J8CAt9rch3My2winC1Jw=
10+
github.com/golang-jwt/jwt/v5 v5.2.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk=
1111
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
1212
github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
1313
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=

token/jwt.go

Lines changed: 32 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,9 @@ import (
99
"net/url"
1010
"path"
1111
"strings"
12+
"time"
1213

13-
"github.com/golang-jwt/jwt/v4"
14+
"github.com/golang-jwt/jwt/v5"
1415
)
1516

1617
type JWT jwt.Token
@@ -108,9 +109,14 @@ func getKey(header map[string]interface{}, keys []map[string]interface{}) (inter
108109
return nil, errors.New("key not found")
109110
}
110111

111-
func toStringArray(a []interface{}) ([]string, bool) {
112-
b := make([]string, len(a))
113-
for i, v := range a {
112+
func toStringArray(a interface{}) ([]string, bool) {
113+
aa, ok := a.([]interface{})
114+
if !ok {
115+
return nil, false
116+
}
117+
118+
b := make([]string, len(aa))
119+
for i, v := range aa {
114120
w, ok := v.(string)
115121
if !ok {
116122
return nil, false
@@ -121,44 +127,34 @@ func toStringArray(a []interface{}) ([]string, bool) {
121127
}
122128

123129
func parseJWT(token string, keys []map[string]interface{}) (*JWT, error) {
124-
t, err := jwt.Parse(token, func(t *jwt.Token) (interface{}, error) {
125-
return getKey(t.Header, keys)
126-
})
130+
t, err := jwt.Parse(
131+
token,
132+
func(t *jwt.Token) (interface{}, error) {
133+
return getKey(t.Header, keys)
134+
},
135+
jwt.WithExpirationRequired(),
136+
jwt.WithIssuedAt(),
137+
jwt.WithLeeway(5*time.Second),
138+
)
127139
if err != nil {
128140
return nil, err
129141
}
130142
return (*JWT)(t), nil
131143
}
132144

133145
func (token *JWT) Check(host, group string, username *string) (string, []string, error) {
134-
claims := token.Claims.(jwt.MapClaims)
135-
136-
s, ok := claims["sub"]
137-
if !ok {
138-
return "", nil, errors.New("token has no 'sub' field")
139-
}
140-
sub, ok := s.(string)
141-
if !ok {
142-
return "", nil, errors.New("invalid 'sub' field")
146+
sub, err := token.Claims.GetSubject()
147+
if err != nil {
148+
return "", nil, err
143149
}
144150
// we accept tokens with a different username from the one provided,
145151
// and use the token's 'sub' field to override the username
146152

147-
var aud []string
148-
if a, ok := claims["aud"]; ok && a != nil {
149-
switch a := a.(type) {
150-
case string:
151-
aud = []string{a}
152-
case []interface{}:
153-
aud, ok = toStringArray(a)
154-
if !ok {
155-
return "", nil, errors.New("invalid 'aud' field")
156-
}
157-
default:
158-
return "", nil, errors.New("invalid 'aud' field")
159-
}
153+
aud, err := token.Claims.GetAudience()
154+
if err != nil {
155+
return "", nil, err
160156
}
161-
ok = false
157+
ok := false
162158
for _, u := range aud {
163159
url, err := url.Parse(u)
164160
if err != nil {
@@ -181,13 +177,14 @@ func (token *JWT) Check(host, group string, username *string) (string, []string,
181177
return "", nil, errors.New("token for wrong group")
182178
}
183179

180+
claims, ok := token.Claims.(jwt.MapClaims)
181+
if !ok {
182+
return "", nil, errors.New("unexpected type for token")
183+
}
184+
184185
var perms []string
185186
if p, ok := claims["permissions"]; ok && p != nil {
186-
pp, ok := p.([]interface{})
187-
if !ok {
188-
return "", nil, errors.New("invalid 'permissions' field")
189-
}
190-
perms, ok = toStringArray(pp)
187+
perms, ok = toStringArray(p)
191188
if !ok {
192189
return "", nil, errors.New("invalid 'permissions' field")
193190
}

token/jwt_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,11 @@ func TestJWT(t *testing.T) {
125125
t.Errorf("Couldn't parse noSubToken: %v", err)
126126
}
127127
username, perms, err = tok.Check("galene.org:8443", "auth", &jack)
128-
if err == nil {
129-
t.Errorf("noSubToken is valid")
128+
if err != nil {
129+
t.Errorf("noSubToken is not valid: %v", err)
130+
}
131+
if username != "" || !reflect.DeepEqual(perms, []string{"present"}) {
132+
t.Errorf("Expected \"\", [present], got %v %v", username, perms)
130133
}
131134

132135
badToken := "eyJ0eXAiOiJKV1QiLCJhbGciOiJub25lIn0.eyJzdWIiOiJqb2huIiwiYXVkIjoiaHR0cHM6Ly9nYWxlbmUub3JnOjg0NDMvZ3JvdXAvYXV0aC8iLCJwZXJtaXNzaW9ucyI6WyJwcmVzZW50Il0sImlhdCI6MTY0NTMxMDQ2OSwiZXhwIjoyOTA2NzUwNDY5LCJpc3MiOiJodHRwOi8vbG9jYWxob3N0OjEyMzQvIn0."

0 commit comments

Comments
 (0)