outposts/proxy: fix redirect path when external host is a subdirectory (#3628)

fix redirect path when external host is a subdirectory

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
Jens L 2022-09-22 10:10:29 +02:00 committed by GitHub
parent f9d9b2716d
commit 49b6aabb02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 1 deletions

View File

@ -25,6 +25,41 @@ func TestProxy_ModifyRequest(t *testing.T) {
assert.Equal(t, "frontend", req.Host) assert.Equal(t, "frontend", req.Host)
} }
func TestProxy_Redirect(t *testing.T) {
a := newTestApplication()
_ = a.configureProxy()
req, _ := http.NewRequest("GET", "https://ext.t.goauthentik.io/foo", nil)
rr := httptest.NewRecorder()
a.mux.ServeHTTP(rr, req)
assert.Equal(t, http.StatusFound, rr.Code)
loc, _ := rr.Result().Location()
assert.Equal(
t,
"https://ext.t.goauthentik.io/outpost.goauthentik.io/start?rd=https%3A%2F%2Fext.t.goauthentik.io%2Ffoo",
loc.String(),
)
}
func TestProxy_Redirect_Subdirectory(t *testing.T) {
a := newTestApplication()
a.proxyConfig.ExternalHost = a.proxyConfig.ExternalHost + "/subdir"
_ = a.configureProxy()
req, _ := http.NewRequest("GET", "https://ext.t.goauthentik.io/foo", nil)
rr := httptest.NewRecorder()
a.mux.ServeHTTP(rr, req)
assert.Equal(t, http.StatusFound, rr.Code)
loc, _ := rr.Result().Location()
assert.Equal(
t,
"https://ext.t.goauthentik.io/subdir/outpost.goauthentik.io/start?rd=https%3A%2F%2Fext.t.goauthentik.io%2Ffoo",
loc.String(),
)
}
func TestProxy_ModifyRequest_Claims(t *testing.T) { func TestProxy_ModifyRequest_Claims(t *testing.T) {
a := newTestApplication() a := newTestApplication()
req, _ := http.NewRequest("GET", "http://frontend/foo", nil) req, _ := http.NewRequest("GET", "http://frontend/foo", nil)

View File

@ -16,6 +16,8 @@ func newTestApplication() *Application {
ClientSecret: api.PtrString(ak.TestSecret()), ClientSecret: api.PtrString(ak.TestSecret()),
CookieSecret: api.PtrString(ak.TestSecret()), CookieSecret: api.PtrString(ak.TestSecret()),
ExternalHost: "https://ext.t.goauthentik.io", ExternalHost: "https://ext.t.goauthentik.io",
InternalHost: api.PtrString("http://backend"),
InternalHostSslValidation: api.PtrBool(true),
CookieDomain: api.PtrString(""), CookieDomain: api.PtrString(""),
Mode: *api.NewNullableProxyMode(api.PROXYMODE_FORWARD_SINGLE.Ptr()), Mode: *api.NewNullableProxyMode(api.PROXYMODE_FORWARD_SINGLE.Ptr()),
SkipPathRegex: api.PtrString("/skip.*"), SkipPathRegex: api.PtrString("/skip.*"),

View File

@ -12,6 +12,15 @@ import (
"goauthentik.io/internal/outpost/proxyv2/constants" "goauthentik.io/internal/outpost/proxyv2/constants"
) )
func urlPathSet(originalUrl string, newPath string) string {
u, err := url.Parse(originalUrl)
if err != nil {
return originalUrl
}
u.Path = newPath
return u.String()
}
func urlJoin(originalUrl string, newPath string) string { func urlJoin(originalUrl string, newPath string) string {
u, err := url.Parse(originalUrl) u, err := url.Parse(originalUrl)
if err != nil { if err != nil {
@ -26,7 +35,9 @@ func (a *Application) redirectToStart(rw http.ResponseWriter, r *http.Request) {
if err != nil { if err != nil {
a.log.WithError(err).Warning("failed to decode session") a.log.WithError(err).Warning("failed to decode session")
} }
redirectUrl := urlJoin(a.proxyConfig.ExternalHost, r.URL.Path)
redirectUrl := urlPathSet(a.proxyConfig.ExternalHost, r.URL.Path)
if a.Mode() == api.PROXYMODE_FORWARD_DOMAIN { if a.Mode() == api.PROXYMODE_FORWARD_DOMAIN {
dom := strings.TrimPrefix(*a.proxyConfig.CookieDomain, ".") dom := strings.TrimPrefix(*a.proxyConfig.CookieDomain, ".")
// In forward_domain we only check that the current URL's host // In forward_domain we only check that the current URL's host