Browse Source

Allow ignoring of specific client token errors

master
William Petit 3 months ago
parent
commit
5f3f508329
2 changed files with 51 additions and 14 deletions
  1. 37
    8
      server/middleware.go
  2. 14
    6
      server/option.go

+ 37
- 8
server/middleware.go View File

@@ -58,7 +58,13 @@ func Authenticate(store peering.Store, key *rsa.PublicKey, funcs ...OptionFunc)
58 58
 				return
59 59
 			}
60 60
 
61
-			clientClaims, err := assertClientToken(serverClaims.PeerID, store, clientToken)
61
+			clientClaims, err := assertClientToken(
62
+				serverClaims.PeerID,
63
+				store,
64
+				clientToken,
65
+				logger,
66
+				options.IgnoredClientTokenErrors...,
67
+			)
62 68
 			if err != nil {
63 69
 				logger.Printf("[ERROR] %s", err)
64 70
 				switch err {
@@ -78,10 +84,11 @@ func Authenticate(store peering.Store, key *rsa.PublicKey, funcs ...OptionFunc)
78 84
 						return
79 85
 					}
80 86
 					sendError(w, http.StatusForbidden)
87
+					return
81 88
 				default:
82 89
 					sendError(w, http.StatusInternalServerError)
90
+					return
83 91
 				}
84
-				return
85 92
 			}
86 93
 
87 94
 			match, body, err := assertBodySum(r.Body, clientClaims.BodySum)
@@ -145,7 +152,7 @@ func assertServerToken(key *rsa.PublicKey, serverToken string) (*peering.ServerT
145 152
 	return claims, nil
146 153
 }
147 154
 
148
-func assertClientToken(peerID peering.PeerID, store peering.Store, clientToken string) (*peering.ClientTokenClaims, error) {
155
+func assertClientToken(peerID peering.PeerID, store peering.Store, clientToken string, logger Logger, ignoredValidationErrors ...uint32) (*peering.ClientTokenClaims, error) {
149 156
 	fn := func(token *jwt.Token) (interface{}, error) {
150 157
 		peer, err := store.Get(peerID)
151 158
 		if err != nil {
@@ -163,22 +170,35 @@ func assertClientToken(peerID peering.PeerID, store peering.Store, clientToken s
163 170
 		}
164 171
 		return publicKey, nil
165 172
 	}
173
+
174
+	getPeeringClaims := func(token *jwt.Token) (*peering.ClientTokenClaims, error) {
175
+		claims, ok := token.Claims.(*peering.ClientTokenClaims)
176
+		if !ok {
177
+			return nil, ErrInvalidClaims
178
+		}
179
+		return claims, nil
180
+	}
181
+
166 182
 	token, err := jwt.ParseWithClaims(clientToken, &peering.ClientTokenClaims{}, fn)
167 183
 	if err != nil {
168 184
 		validationError, ok := err.(*jwt.ValidationError)
169 185
 		if ok {
186
+			for _, c := range ignoredValidationErrors {
187
+				if validationError.Errors&c != 0 {
188
+					logger.Printf("ignoring token validation error: '%s'", validationError.Inner)
189
+					return getPeeringClaims(token)
190
+				}
191
+			}
170 192
 			return nil, validationError.Inner
171 193
 		}
172 194
 		return nil, err
173 195
 	}
196
+
174 197
 	if !token.Valid {
175 198
 		return nil, ErrInvalidClaims
176 199
 	}
177
-	claims, ok := token.Claims.(*peering.ClientTokenClaims)
178
-	if !ok {
179
-		return nil, ErrInvalidClaims
180
-	}
181
-	return claims, nil
200
+
201
+	return getPeeringClaims(token)
182 202
 }
183 203
 
184 204
 func assertBodySum(rc io.ReadCloser, bodySum []byte) (bool, []byte, error) {
@@ -200,6 +220,15 @@ func sendError(w http.ResponseWriter, status int) {
200 220
 	http.Error(w, http.StatusText(status), status)
201 221
 }
202 222
 
223
+func filterIgnoredValidationError(err *jwt.ValidationError, ignored ...uint32) error {
224
+	for _, c := range ignored {
225
+		if err.Errors&c != 0 {
226
+			return nil
227
+		}
228
+	}
229
+	return err
230
+}
231
+
203 232
 func compareChecksum(body []byte, sum []byte) (bool, error) {
204 233
 	sha := sha256.New()
205 234
 	_, err := sha.Write(body)

+ 14
- 6
server/option.go View File

@@ -11,9 +11,10 @@ type Logger interface {
11 11
 }
12 12
 
13 13
 type Options struct {
14
-	PeerAttributes []string
15
-	ErrorHandler   ErrorHandler
16
-	Logger         Logger
14
+	PeerAttributes           []string
15
+	ErrorHandler             ErrorHandler
16
+	Logger                   Logger
17
+	IgnoredClientTokenErrors []uint32
17 18
 }
18 19
 
19 20
 type OptionFunc func(*Options)
@@ -38,12 +39,19 @@ func WithErrorHandler(handler ErrorHandler) OptionFunc {
38 39
 	}
39 40
 }
40 41
 
42
+func WithIgnoredClientTokenErrors(codes ...uint32) OptionFunc {
43
+	return func(options *Options) {
44
+		options.IgnoredClientTokenErrors = codes
45
+	}
46
+}
47
+
41 48
 func defaultOptions() *Options {
42 49
 	logger := log.New(os.Stdout, "[go-http-peering] ", log.LstdFlags|log.Lshortfile)
43 50
 	return &Options{
44
-		PeerAttributes: []string{"Label"},
45
-		ErrorHandler:   DefaultErrorHandler,
46
-		Logger:         logger,
51
+		PeerAttributes:           []string{"Label"},
52
+		ErrorHandler:             DefaultErrorHandler,
53
+		Logger:                   logger,
54
+		IgnoredClientTokenErrors: make([]uint32, 0),
47 55
 	}
48 56
 }
49 57
 

Loading…
Cancel
Save