diff --git a/acceptance_test.go b/acceptance_test.go index eaa32318f27d1685230f1d946c350cb9005d4ec8..476f474be53e519369d09563bb2175fb78934937 100644 --- a/acceptance_test.go +++ b/acceptance_test.go @@ -931,6 +931,72 @@ func TestAccessControlUnderCustomDomain(t *testing.T) { assert.Equal(t, http.StatusOK, authrsp.StatusCode) } +func TestAccessControlUnderCustomDomainWithSSLOffloading(t *testing.T) { + skipUnlessEnabled(t, "not-inplace-chroot") + + testServer := makeGitLabPagesAccessStub(t) + testServer.Start() + defer testServer.Close() + + teardown := RunPagesProcessWithAuthServer(t, *pagesBinary, listeners, "", testServer.URL) + defer teardown() + + rsp, err := GetRedirectPageWithCookieAndProto(t, httpListener, "private.domain.com", "/", "", "https") + require.NoError(t, err) + defer rsp.Body.Close() + + cookie := rsp.Header.Get("Set-Cookie") + + url, err := url.Parse(rsp.Header.Get("Location")) + require.NoError(t, err) + + state := url.Query().Get("state") + assert.Equal(t, url.Query().Get("domain"), "https://private.domain.com") + + pagesrsp, err := GetRedirectPageWithCookieAndProto(t, httpListener, url.Host, url.Path+"?"+url.RawQuery, "", "https") + require.NoError(t, err) + defer pagesrsp.Body.Close() + + pagescookie := pagesrsp.Header.Get("Set-Cookie") + + // Go to auth page with correct state will cause fetching the token + authrsp, err := GetRedirectPageWithCookieAndProto(t, httpListener, "projects.gitlab-example.com", "/auth?code=1&state="+ + state, pagescookie, "https") + + require.NoError(t, err) + defer authrsp.Body.Close() + + url, err = url.Parse(authrsp.Header.Get("Location")) + require.NoError(t, err) + + // Will redirect to custom domain + assert.Equal(t, "https", url.Scheme) + assert.Equal(t, "private.domain.com", url.Host) + assert.Equal(t, "1", url.Query().Get("code")) + assert.Equal(t, state, url.Query().Get("state")) + + // Run auth callback in custom domain + authrsp, err = GetRedirectPageWithCookieAndProto(t, httpListener, "private.domain.com", "/auth?code=1&state="+ + state, cookie, "https") + + require.NoError(t, err) + defer authrsp.Body.Close() + + // Will redirect to the page + cookie = authrsp.Header.Get("Set-Cookie") + assert.Equal(t, http.StatusFound, authrsp.StatusCode) + + url, err = url.Parse(authrsp.Header.Get("Location")) + require.NoError(t, err) + + // Will redirect to custom domain + assert.Equal(t, "https://private.domain.com/", url.String()) + + // Fetch page in custom domain + authrsp, err = GetRedirectPageWithCookieAndProto(t, httpListener, "private.domain.com", "/", cookie, "https") + assert.Equal(t, http.StatusOK, authrsp.StatusCode) +} + func TestAccessControlGroupDomain404RedirectsAuth(t *testing.T) { skipUnlessEnabled(t) teardown := RunPagesProcessWithAuth(t, *pagesBinary, listeners, "") diff --git a/helpers_test.go b/helpers_test.go index 61fa527921d8f228382772e0719126ea323bcd82..c8954614f8f6388ad9358bc0e67fab2cd04f585d 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -315,11 +315,18 @@ func GetRedirectPage(t *testing.T, spec ListenSpec, host, urlsuffix string) (*ht } func GetRedirectPageWithCookie(t *testing.T, spec ListenSpec, host, urlsuffix string, cookie string) (*http.Response, error) { + return GetRedirectPageWithCookieAndProto(t, spec, host, urlsuffix, cookie, "") +} + +func GetRedirectPageWithCookieAndProto(t *testing.T, spec ListenSpec, host, urlsuffix string, cookie string, proto string) (*http.Response, error) { url := spec.URL(urlsuffix) req, err := http.NewRequest("GET", url, nil) if err != nil { return nil, err } + if proto != "" { + req.Header.Set("X-Forwarded-Proto", proto) + } if cookie != "" { req.Header.Set("Cookie", cookie) } diff --git a/internal/auth/auth.go b/internal/auth/auth.go index 02879568c2f236afadb559d33c7f80e55847509c..acd72227d6666ff8797067f15630ab185a805cf7 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -255,19 +255,24 @@ func (a *Auth) handleProxyingAuth(session *sessions.Session, w http.ResponseWrit return false } - -func getRequestAddress(r *http.Request) string { +func getRequestProto(r *http.Request) string { + if val, ok := r.Header["X-Forwarded-Proto"]; ok { + proto := val[0] + if proto == "http" || proto == "https" { + return proto + } + } if r.TLS != nil { - return "https://" + r.Host + r.RequestURI + return "https" } - return "http://" + r.Host + r.RequestURI + return "http" +} +func getRequestAddress(r *http.Request) string { + return getRequestProto(r) + "://" + r.Host + r.RequestURI } func getRequestDomain(r *http.Request) string { - if r.TLS != nil { - return "https://" + r.Host - } - return "http://" + r.Host + return getRequestProto(r) + "://" + r.Host } func shouldProxyAuth(r *http.Request) bool {