1 package jwt
2
3 import (
4 "bytes"
5 "encoding/base64"
6 "encoding/json"
7 "fmt"
8 "strings"
9 )
10
11 type Parser struct {
12
13 validMethods []string
14
15
16 useJSONNumber bool
17
18
19 skipClaimsValidation bool
20
21 validator *Validator
22
23 decodeStrict bool
24
25 decodePaddingAllowed bool
26 }
27
28
29 func NewParser(options ...ParserOption) *Parser {
30 p := &Parser{
31 validator: &Validator{},
32 }
33
34
35 for _, option := range options {
36 option(p)
37 }
38
39 return p
40 }
41
42
43
44 func (p *Parser) Parse(tokenString string, keyFunc Keyfunc) (*Token, error) {
45 return p.ParseWithClaims(tokenString, MapClaims{}, keyFunc)
46 }
47
48
49
50
51
52
53
54
55 func (p *Parser) ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc) (*Token, error) {
56 token, parts, err := p.ParseUnverified(tokenString, claims)
57 if err != nil {
58 return token, err
59 }
60
61
62 if p.validMethods != nil {
63 var signingMethodValid = false
64 var alg = token.Method.Alg()
65 for _, m := range p.validMethods {
66 if m == alg {
67 signingMethodValid = true
68 break
69 }
70 }
71 if !signingMethodValid {
72
73 return token, newError(fmt.Sprintf("signing method %v is invalid", alg), ErrTokenSignatureInvalid)
74 }
75 }
76
77
78 token.Signature, err = p.DecodeSegment(parts[2])
79 if err != nil {
80 return token, newError("could not base64 decode signature", ErrTokenMalformed, err)
81 }
82 text := strings.Join(parts[0:2], ".")
83
84
85 if keyFunc == nil {
86
87 return token, newError("no keyfunc was provided", ErrTokenUnverifiable)
88 }
89
90 got, err := keyFunc(token)
91 if err != nil {
92 return token, newError("error while executing keyfunc", ErrTokenUnverifiable, err)
93 }
94
95 switch have := got.(type) {
96 case VerificationKeySet:
97 if len(have.Keys) == 0 {
98 return token, newError("keyfunc returned empty verification key set", ErrTokenUnverifiable)
99 }
100
101
102 for _, key := range have.Keys {
103 if err = token.Method.Verify(text, token.Signature, key); err == nil {
104 break
105 }
106 }
107 default:
108 err = token.Method.Verify(text, token.Signature, have)
109 }
110 if err != nil {
111 return token, newError("", ErrTokenSignatureInvalid, err)
112 }
113
114
115 if !p.skipClaimsValidation {
116
117 if p.validator == nil {
118 p.validator = NewValidator()
119 }
120
121 if err := p.validator.Validate(claims); err != nil {
122 return token, newError("", ErrTokenInvalidClaims, err)
123 }
124 }
125
126
127 token.Valid = true
128
129 return token, nil
130 }
131
132
133
134
135
136
137
138 func (p *Parser) ParseUnverified(tokenString string, claims Claims) (token *Token, parts []string, err error) {
139 parts = strings.Split(tokenString, ".")
140 if len(parts) != 3 {
141 return nil, parts, newError("token contains an invalid number of segments", ErrTokenMalformed)
142 }
143
144 token = &Token{Raw: tokenString}
145
146
147 var headerBytes []byte
148 if headerBytes, err = p.DecodeSegment(parts[0]); err != nil {
149 return token, parts, newError("could not base64 decode header", ErrTokenMalformed, err)
150 }
151 if err = json.Unmarshal(headerBytes, &token.Header); err != nil {
152 return token, parts, newError("could not JSON decode header", ErrTokenMalformed, err)
153 }
154
155
156 token.Claims = claims
157
158 claimBytes, err := p.DecodeSegment(parts[1])
159 if err != nil {
160 return token, parts, newError("could not base64 decode claim", ErrTokenMalformed, err)
161 }
162
163
164
165
166 if !p.useJSONNumber {
167
168 if c, ok := token.Claims.(MapClaims); ok {
169 err = json.Unmarshal(claimBytes, &c)
170 } else {
171 err = json.Unmarshal(claimBytes, &claims)
172 }
173 } else {
174 dec := json.NewDecoder(bytes.NewBuffer(claimBytes))
175 dec.UseNumber()
176
177 if c, ok := token.Claims.(MapClaims); ok {
178 err = dec.Decode(&c)
179 } else {
180 err = dec.Decode(&claims)
181 }
182 }
183 if err != nil {
184 return token, parts, newError("could not JSON decode claim", ErrTokenMalformed, err)
185 }
186
187
188 if method, ok := token.Header["alg"].(string); ok {
189 if token.Method = GetSigningMethod(method); token.Method == nil {
190 return token, parts, newError("signing method (alg) is unavailable", ErrTokenUnverifiable)
191 }
192 } else {
193 return token, parts, newError("signing method (alg) is unspecified", ErrTokenUnverifiable)
194 }
195
196 return token, parts, nil
197 }
198
199
200
201
202 func (p *Parser) DecodeSegment(seg string) ([]byte, error) {
203 encoding := base64.RawURLEncoding
204
205 if p.decodePaddingAllowed {
206 if l := len(seg) % 4; l > 0 {
207 seg += strings.Repeat("=", 4-l)
208 }
209 encoding = base64.URLEncoding
210 }
211
212 if p.decodeStrict {
213 encoding = encoding.Strict()
214 }
215 return encoding.DecodeString(seg)
216 }
217
218
219
220
221
222
223
224
225 func Parse(tokenString string, keyFunc Keyfunc, options ...ParserOption) (*Token, error) {
226 return NewParser(options...).Parse(tokenString, keyFunc)
227 }
228
229
230
231
232
233
234
235
236 func ParseWithClaims(tokenString string, claims Claims, keyFunc Keyfunc, options ...ParserOption) (*Token, error) {
237 return NewParser(options...).ParseWithClaims(tokenString, claims, keyFunc)
238 }
239
View as plain text