From 8447e9b9c273b3dad4e817002ad1612ee5ec05b7 Mon Sep 17 00:00:00 2001 From: Jens L Date: Fri, 3 Jun 2022 10:32:52 +0200 Subject: [PATCH] providers/proxy: envoy v2 (#3029) * add path prefix Signed-off-by: Jens Langhammer * use prefix correctly Signed-off-by: Jens Langhammer * only set redirect if session doesn't have a redirect yet Signed-off-by: Jens Langhammer --- .../proxyv2/application/application.go | 1 - .../proxyv2/application/mode_forward.go | 25 ++++++++++--------- .../application/mode_forward_envoy_test.go | 4 +-- internal/outpost/proxyv2/metrics/metrics.go | 2 +- website/docs/providers/proxy/_envoy_istio.md | 1 + 5 files changed, 17 insertions(+), 16 deletions(-) diff --git a/internal/outpost/proxyv2/application/application.go b/internal/outpost/proxyv2/application/application.go index ced46b374..a127a2ba2 100644 --- a/internal/outpost/proxyv2/application/application.go +++ b/internal/outpost/proxyv2/application/application.go @@ -136,7 +136,6 @@ func NewApplication(p api.ProxyOutpostConfig, c *http.Client, cs *ak.CryptoStore "type": "app", "method": r.Method, "host": web.GetHost(r), - "scheme": r.URL.Scheme, }).Observe(float64(after)) }) }) diff --git a/internal/outpost/proxyv2/application/mode_forward.go b/internal/outpost/proxyv2/application/mode_forward.go index 1be5e9fe7..9dee51d4b 100644 --- a/internal/outpost/proxyv2/application/mode_forward.go +++ b/internal/outpost/proxyv2/application/mode_forward.go @@ -11,6 +11,10 @@ import ( "goauthentik.io/internal/utils/web" ) +const ( + envoyPrefix = "/outpost.goauthentik.io/auth/envoy" +) + func (a *Application) configureForward() error { a.mux.HandleFunc("/outpost.goauthentik.io/auth", func(rw http.ResponseWriter, r *http.Request) { if _, ok := r.URL.Query()["traefik"]; ok { @@ -21,7 +25,7 @@ func (a *Application) configureForward() error { }) a.mux.HandleFunc("/outpost.goauthentik.io/auth/traefik", a.forwardHandleTraefik) a.mux.HandleFunc("/outpost.goauthentik.io/auth/nginx", a.forwardHandleNginx) - a.mux.PathPrefix("/").HandlerFunc(a.forwardHandleEnvoy) + a.mux.PathPrefix(envoyPrefix).HandlerFunc(a.forwardHandleEnvoy) return nil } @@ -130,6 +134,7 @@ func (a *Application) forwardHandleNginx(rw http.ResponseWriter, r *http.Request func (a *Application) forwardHandleEnvoy(rw http.ResponseWriter, r *http.Request) { a.log.WithField("header", r.Header).Trace("tracing headers for debug") + r.URL.Path = strings.TrimPrefix(r.URL.Path, envoyPrefix) fwd := r.URL claims, err := a.getClaims(r) @@ -163,18 +168,14 @@ func (a *Application) forwardHandleEnvoy(rw http.ResponseWriter, r *http.Request // to a (possibly) different domain, but we want to be redirected back // to the application // X-Forwarded-Uri is only the path, so we need to build the entire URL - s.Values[constants.SessionRedirect] = fwd.String() - err = s.Save(r, rw) - if err != nil { - a.log.WithError(err).Warning("failed to save session before redirect") + if _, redirectSet := s.Values[constants.SessionRedirect]; !redirectSet { + s.Values[constants.SessionRedirect] = fwd.String() + err = s.Save(r, rw) + if err != nil { + a.log.WithError(err).Warning("failed to save session before redirect") + } } - // We mostly can't rely on X-Forwarded-Proto here since in most cases that will come from the - // local Envoy sidecar, so we re-used the same proto as the original URL had - scheme := r.Header.Get("X-Forwarded-Proto") - if scheme == "" { - scheme = "http:" - } - rdFinal := fmt.Sprintf("%s//%s%s", scheme, host, "/outpost.goauthentik.io/start") + rdFinal := fmt.Sprintf("//%s%s", host, "/outpost.goauthentik.io/start") a.log.WithField("url", rdFinal).Debug("Redirecting to login") http.Redirect(rw, r, rdFinal, http.StatusTemporaryRedirect) } diff --git a/internal/outpost/proxyv2/application/mode_forward_envoy_test.go b/internal/outpost/proxyv2/application/mode_forward_envoy_test.go index 83f2107d9..3f5c3a488 100644 --- a/internal/outpost/proxyv2/application/mode_forward_envoy_test.go +++ b/internal/outpost/proxyv2/application/mode_forward_envoy_test.go @@ -29,7 +29,7 @@ func TestForwardHandleEnvoy_Single_Headers(t *testing.T) { assert.Equal(t, rr.Code, http.StatusTemporaryRedirect) loc, _ := rr.Result().Location() - assert.Equal(t, loc.String(), "http://test.goauthentik.io/outpost.goauthentik.io/start") + assert.Equal(t, loc.String(), "//test.goauthentik.io/outpost.goauthentik.io/start") s, _ := a.sessions.Get(req, constants.SessionName) assert.Equal(t, "http://test.goauthentik.io/app", s.Values[constants.SessionRedirect]) @@ -91,7 +91,7 @@ func TestForwardHandleEnvoy_Domain_Header(t *testing.T) { assert.Equal(t, http.StatusTemporaryRedirect, rr.Code) loc, _ := rr.Result().Location() - assert.Equal(t, "http://auth.test.goauthentik.io/outpost.goauthentik.io/start", loc.String()) + assert.Equal(t, "//auth.test.goauthentik.io/outpost.goauthentik.io/start", loc.String()) s, _ := a.sessions.Get(req, constants.SessionName) assert.Equal(t, "http://test.goauthentik.io/app", s.Values[constants.SessionRedirect]) diff --git a/internal/outpost/proxyv2/metrics/metrics.go b/internal/outpost/proxyv2/metrics/metrics.go index 53468d51e..770d2ce01 100644 --- a/internal/outpost/proxyv2/metrics/metrics.go +++ b/internal/outpost/proxyv2/metrics/metrics.go @@ -15,7 +15,7 @@ var ( Requests = promauto.NewHistogramVec(prometheus.HistogramOpts{ Name: "authentik_outpost_proxy_requests", Help: "The total number of configured providers", - }, []string{"outpost_name", "method", "scheme", "host", "type"}) + }, []string{"outpost_name", "method", "host", "type"}) UpstreamTiming = promauto.NewHistogramVec(prometheus.HistogramOpts{ Name: "authentik_outpost_proxy_upstream_time", Help: "A summary of the duration we wait for the upstream reply", diff --git a/website/docs/providers/proxy/_envoy_istio.md b/website/docs/providers/proxy/_envoy_istio.md index c321b6221..c72e8f1e3 100644 --- a/website/docs/providers/proxy/_envoy_istio.md +++ b/website/docs/providers/proxy/_envoy_istio.md @@ -14,6 +14,7 @@ spec: # Replace with ..svc.cluster.local service: "ak-outpost-authentik-embedded-outpost.authentik.svc.cluster.local" port: "9000" + pathPrefix: "/outpost.goauthentik.io/auth/envoy" headersToDownstreamOnAllow: - cookie headersToUpstreamOnAllow: