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
1617type 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
123129func 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
133145func (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 }
0 commit comments