Skip to content

Commit dbaac3e

Browse files
committed
adding optional mode
1 parent c0f998d commit dbaac3e

File tree

3 files changed

+61
-0
lines changed

3 files changed

+61
-0
lines changed

internal/jwt/validator.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ type Validator struct {
2424
jwkSet jwk.Set
2525
parserOptions []jwt.ParseOption
2626
audiences []string
27+
optional bool
2728
}
2829

2930
var globalParserOptions = []jwt.ParseOption{
@@ -196,3 +197,19 @@ func (v *Validator) ParseHTTPRequest(r *http.Request) (accessToken jwt.Token, re
196197
return nil, res
197198
}
198199
}
200+
201+
// EnableOptional allows the validator to run optional and ignore all errors
202+
// that appear and still let the request pass
203+
func (r *Validator) EnableOptional() {
204+
r.optional = true
205+
}
206+
207+
// DisableOptional forces the validator to run in the default mode and only
208+
// let requests pass that are not optional
209+
func (r *Validator) DisableOptional() {
210+
r.optional = false
211+
}
212+
213+
func (r *Validator) IsOptional() bool {
214+
return r.optional
215+
}

middleware/gin/jwt/validator.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,40 @@ func (r *Validator) Handler(c *gin.Context) {
1616
headers := c.Request.Header["Authorization"]
1717
switch {
1818
case len(headers) == 0:
19+
if r.IsOptional() {
20+
c.Next()
21+
return
22+
}
1923
c.Abort()
2024
jwt.ErrMissingAuthorizationHeader.Emit(c)
2125
return
2226
case len(headers) > 1:
27+
if r.IsOptional() {
28+
c.Next()
29+
return
30+
}
2331
c.Abort()
2432
jwt.ErrSingleAuthorizationHeaderOnly.Emit(c)
2533
return
2634
}
2735

2836
val := strings.TrimSpace(headers[0])
2937
if !jwt.TokenSchemeRegexCompiled.MatchString(val) {
38+
if r.IsOptional() {
39+
c.Next()
40+
return
41+
}
3042
c.Abort()
3143
jwt.ErrUnsupportedTokenScheme.Emit(c)
3244
return
3345
}
3446

3547
token, err := r.ParseHTTPRequest(c.Request)
3648
if err != nil {
49+
if r.IsOptional() {
50+
c.Next()
51+
return
52+
}
3753
c.Abort()
3854
err.Emit(c)
3955
return
@@ -42,6 +58,10 @@ func (r *Validator) Handler(c *gin.Context) {
4258
iface := token.PrivateClaims()["scopes"]
4359
ifaceArray, isArray := iface.([]any)
4460
if !isArray {
61+
if r.IsOptional() {
62+
c.Next()
63+
return
64+
}
4565
c.Abort()
4666
jwt.ErrJWTInvalidScopeType.Emit(c)
4767
return
@@ -50,6 +70,10 @@ func (r *Validator) Handler(c *gin.Context) {
5070
for _, s := range ifaceArray {
5171
scope, ok := s.(string)
5272
if !ok {
73+
if r.IsOptional() {
74+
c.Next()
75+
return
76+
}
5377
c.Abort()
5478
jwt.ErrJWTInvalidScopeType.Emit(c)
5579
return

middleware/stdlib/jwt/validator.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,47 @@ func (v *Validator) Handler(next http.Handler) http.Handler {
1818
headers := r.Header["Authorization"]
1919
switch {
2020
case len(headers) == 0:
21+
if v.IsOptional() {
22+
next.ServeHTTP(w, r)
23+
return
24+
}
2125
jwt.ErrMissingAuthorizationHeader.Emit(w)
2226
return
2327
case len(headers) > 1:
28+
if v.IsOptional() {
29+
next.ServeHTTP(w, r)
30+
return
31+
}
2432
jwt.ErrSingleAuthorizationHeaderOnly.Emit(w)
2533
return
2634
}
2735

2836
val := strings.TrimSpace(headers[0])
2937
if !jwt.TokenSchemeRegexCompiled.MatchString(val) {
38+
if v.IsOptional() {
39+
next.ServeHTTP(w, r)
40+
return
41+
}
3042
jwt.ErrUnsupportedTokenScheme.Emit(w)
3143
return
3244
}
3345

3446
token, err := v.ParseHTTPRequest(r)
3547
if err != nil {
48+
if v.IsOptional() {
49+
next.ServeHTTP(w, r)
50+
return
51+
}
3652
err.Emit(w)
3753
return
3854
}
3955

4056
scopes, correctType := token.PrivateClaims()["scopes"].([]string)
4157
if !correctType {
58+
if v.IsOptional() {
59+
next.ServeHTTP(w, r)
60+
return
61+
}
4262
jwt.ErrJWTMalformed.Emit(w)
4363
return
4464
}

0 commit comments

Comments
 (0)