@@ -65,15 +65,35 @@ func (r *jwtFileReader) readToken() (string, time.Time, error) {
6565 return token , exp , nil
6666}
6767
68+ const tokenDelim = "."
69+
70+ // extractClaimsRaw returns the JWT's claims part as raw string. Even though the
71+ // header and signature are not used, it still expects that the input string to
72+ // be well-formed (ie comprised of exactly three parts, separated by a dot
73+ // character).
74+ func extractClaimsRaw (s string ) (string , bool ) {
75+ _ , s , ok := strings .Cut (s , tokenDelim )
76+ if ! ok { // no period found
77+ return "" , false
78+ }
79+ claims , s , ok := strings .Cut (s , tokenDelim )
80+ if ! ok { // only one period found
81+ return "" , false
82+ }
83+ _ , _ , ok = strings .Cut (s , tokenDelim )
84+ if ok { // three periods found
85+ return "" , false
86+ }
87+ return claims , true
88+ }
89+
6890// extractExpiration parses the JWT token to extract the expiration time.
6991func (r * jwtFileReader ) extractExpiration (token string ) (time.Time , error ) {
70- parts := strings . Split (token , "." )
71- if len ( parts ) != 3 {
72- return time.Time {}, fmt .Errorf ("expected 3 parts, got %d" , len ( parts ) )
92+ claimsRaw , ok := extractClaimsRaw (token )
93+ if ! ok {
94+ return time.Time {}, fmt .Errorf ("expected 3 parts in token" )
7395 }
74-
75- payload := parts [1 ]
76- payloadBytes , err := base64 .RawURLEncoding .DecodeString (payload )
96+ payloadBytes , err := base64 .RawURLEncoding .DecodeString (claimsRaw )
7797 if err != nil {
7898 return time.Time {}, fmt .Errorf ("decode error: %v" , err )
7999 }
0 commit comments