From 6beca8f59b2ec861a9ca649335acc63cbd55f121 Mon Sep 17 00:00:00 2001 From: Alex Ellis Date: Fri, 7 Jun 2019 09:37:03 +0100 Subject: [PATCH] Pass headers when using external auth Fixes issue found in e2e testing where the headers were not being passed to the basic-auth-plugin. This change makes sure the upstream check gets all headers copied in before making the call. Tested with negative unit tests before writing fix. Signed-off-by: Alex Ellis --- gateway/handlers/external_auth.go | 2 + gateway/handlers/external_auth_test.go | 60 ++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/gateway/handlers/external_auth.go b/gateway/handlers/external_auth.go index f4c429b6..129ce96d 100644 --- a/gateway/handlers/external_auth.go +++ b/gateway/handlers/external_auth.go @@ -11,6 +11,8 @@ func MakeExternalAuthHandler(next http.HandlerFunc, upstreamTimeout time.Duratio return func(w http.ResponseWriter, r *http.Request) { req, _ := http.NewRequest(http.MethodGet, upstreamURL, nil) + copyHeaders(req.Header, &r.Header) + deadlineContext, cancel := context.WithTimeout( context.Background(), upstreamTimeout) diff --git a/gateway/handlers/external_auth_test.go b/gateway/handlers/external_auth_test.go index 43688529..361aa497 100644 --- a/gateway/handlers/external_auth_test.go +++ b/gateway/handlers/external_auth_test.go @@ -53,6 +53,66 @@ func Test_External_Auth_Wrapper_PassesValidAuth(t *testing.T) { } } +func Test_External_Auth_Wrapper_WithoutRequiredHeaderFailsAuth(t *testing.T) { + wantToken := "secret-key" + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Header.Get("X-Token") == wantToken { + w.WriteHeader(http.StatusOK) + return + } + w.WriteHeader(http.StatusUnauthorized) + })) + defer s.Close() + + next := func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) + } + + passBody := false + handler := MakeExternalAuthHandler(next, time.Second*5, s.URL, passBody) + + req := httptest.NewRequest(http.MethodGet, s.URL, nil) + + // use an invalid token + req.Header.Set("X-Token", "invalid-key") + + rr := httptest.NewRecorder() + handler(rr, req) + want := http.StatusUnauthorized + if rr.Code != want { + t.Errorf("Status incorrect, want: %d, but got %d", want, rr.Code) + } +} + +func Test_External_Auth_Wrapper_WithRequiredHeaderPassesValidAuth(t *testing.T) { + wantToken := "secret-key" + s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if r.Header.Get("X-Token") == wantToken { + w.WriteHeader(http.StatusOK) + return + } + w.WriteHeader(http.StatusUnauthorized) + })) + defer s.Close() + + next := func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusNotImplemented) + } + + passBody := false + handler := MakeExternalAuthHandler(next, time.Second*5, s.URL, passBody) + + req := httptest.NewRequest(http.MethodGet, s.URL, nil) + req.Header.Set("X-Token", wantToken) + + rr := httptest.NewRecorder() + handler(rr, req) + want := http.StatusNotImplemented + if rr.Code != want { + t.Errorf("Status incorrect, want: %d, but got %d", want, rr.Code) + } +} + func Test_External_Auth_Wrapper_TimeoutGivesInternalServerError(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {