From b60d29fae8d07677faeafe30f4618c3a951c7efe Mon Sep 17 00:00:00 2001 From: tillkuhn Date: Thu, 8 Feb 2024 09:57:44 +0100 Subject: [PATCH] support x-auth and auth authorization headers (mainly for grafana) --- go/imagine/Makefile | 3 ++- go/imagine/auth/middleware.go | 7 +++++-- go/imagine/auth/middleware_test.go | 11 +++++++---- go/imagine/server/http_test.go | 2 +- 4 files changed, 15 insertions(+), 8 deletions(-) diff --git a/go/imagine/Makefile b/go/imagine/Makefile index fda05949..ea188509 100644 --- a/go/imagine/Makefile +++ b/go/imagine/Makefile @@ -84,8 +84,9 @@ get-health: ## test health check get: ## test get files for id curl -Ss $(BASE_URL)/imagine/places/$(TEST_ID) |jq . +# X-Authorization and Authorization should work both get-metrics: ## get prometheus metrics - curl -isSH "X-Authorization: Bearer $(JWT_TOKEN)" $(BASE_URL)/imagine/metrics + curl -isSH "Authorization: Bearer $(JWT_TOKEN)" $(BASE_URL)/imagine/metrics get-presign-url: ## test get files for id curl -i -Ss $(BASE_URL)/imagine/places/$(TEST_ID)/hase2.jpeg diff --git a/go/imagine/auth/middleware.go b/go/imagine/auth/middleware.go index efef776a..aac16eeb 100644 --- a/go/imagine/auth/middleware.go +++ b/go/imagine/auth/middleware.go @@ -54,7 +54,10 @@ func (ah *Handler) ValidationMiddleware(next http.HandlerFunc) http.HandlerFunc // TODO Delegate to middleware, e.g. like this // https://hackernoon.com/creating-a-middleware-in-golang-for-jwt-based-authentication-cx3f32z8 if ah.enabled { - authHeader := req.Header.Get("X-Authorization") + authHeader := req.Header.Get("X-Authorization") // case-insensitive + if authHeader == "" { + authHeader = req.Header.Get("Authorization") // fallback (e.g. for Grafana metrics scraping) + } if strings.Contains(authHeader, "Bearer") { jwtB64 := strings.Split(authHeader, "Bearer ")[1] claims, err := ah.jwtAuth.ParseClaims(authHeader) @@ -74,7 +77,7 @@ func (ah *Handler) ValidationMiddleware(next http.HandlerFunc) http.HandlerFunc claims.Subject(), claims.Scope(), claims.Roles(), claims.Name(), reflect.TypeOf(claims.Roles())) context.Set(req, ContextAuthKey, claims) } else { - handleError(w, fmt.Sprintf("Cannot find/validate X-Authorization header in %v", req.Header), errors.New("oops"), http.StatusForbidden) + handleError(w, fmt.Sprintf("Cannot find/validate (X-)Authorization header in %v", req.Header), errors.New("oops"), http.StatusForbidden) return } } else { diff --git a/go/imagine/auth/middleware_test.go b/go/imagine/auth/middleware_test.go index e44df878..5fc47d60 100644 --- a/go/imagine/auth/middleware_test.go +++ b/go/imagine/auth/middleware_test.go @@ -39,8 +39,11 @@ func TestValidTokenInvalidMiddleware(t *testing.T) { req, _ := http.NewRequest("POST", "/sandbox/can-i-upload.txt", nil) testHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}) // encToken, _ := issueToken("extra-protected") - req.Header.Set("X-Authorization", "Bearer invalid-string") - authContextEnabled.ValidationMiddleware(testHandler).ServeHTTP(rr, req) - assert.Equal(t, rr.Code, http.StatusForbidden, rr.Body.String()) - assert.Contains(t, strings.ToLower(rr.Body.String()), "invalid number of segments") + // both headers should be checked + for _, ah := range []string{"X-Authorization", "Authorization"} { + req.Header.Set(ah, "Bearer invalid-string") + authContextEnabled.ValidationMiddleware(testHandler).ServeHTTP(rr, req) + assert.Equal(t, rr.Code, http.StatusForbidden, rr.Body.String()) + assert.Contains(t, strings.ToLower(rr.Body.String()), "invalid number of segments") + } } diff --git a/go/imagine/server/http_test.go b/go/imagine/server/http_test.go index e94e6d75..125abe7c 100644 --- a/go/imagine/server/http_test.go +++ b/go/imagine/server/http_test.go @@ -58,7 +58,7 @@ func TestShouldRejectPostIfUnauthenticated(t *testing.T) { fmt.Println(targetUrl) filename := "../README.md" err = postFile(filename, targetUrl) - assert.Contains(t, err.Error(), "X-Authorization header") + assert.Contains(t, err.Error(), "Authorization header") assert.Contains(t, err.Error(), "403") }