From e24997a0028ff928412abd0294e52693fd4570eb Mon Sep 17 00:00:00 2001 From: p53 Date: Sun, 21 Jul 2024 13:38:30 +0200 Subject: [PATCH] Enable to forward-auth to work with static authz (#488) --- pkg/keycloak/proxy/server.go | 4 ++++ pkg/proxy/middleware/base.go | 20 ++++++++++++++++++++ pkg/testsuite/server_test.go | 34 +++++++++++++++++++++++++++++++--- 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/pkg/keycloak/proxy/server.go b/pkg/keycloak/proxy/server.go index 4baf98d2..f82a7c11 100644 --- a/pkg/keycloak/proxy/server.go +++ b/pkg/keycloak/proxy/server.go @@ -247,6 +247,10 @@ func (r *OauthProxy) useDefaultStack(engine chi.Router) { // @step: enable the entrypoint middleware engine.Use(gmiddleware.EntrypointMiddleware(r.Log)) + if r.Config.NoProxy { + engine.Use(gmiddleware.ForwardAuthMiddleware(r.Log, r.Config.OAuthURI)) + } + if r.Config.EnableLogging { engine.Use(gmiddleware.LoggingMiddleware(r.Log, r.Config.Verbose)) } diff --git a/pkg/proxy/middleware/base.go b/pkg/proxy/middleware/base.go index e9822621..99ebfe55 100644 --- a/pkg/proxy/middleware/base.go +++ b/pkg/proxy/middleware/base.go @@ -372,3 +372,23 @@ func ProxyMiddleware( }) } } + +// ForwardAuthMiddleware +func ForwardAuthMiddleware(logger *zap.Logger, oAuthURI string) func(http.Handler) http.Handler { + return func(next http.Handler) http.Handler { + logger.Info("enabling the forward-auth middleware") + + return http.HandlerFunc(func(wrt http.ResponseWriter, req *http.Request) { + if !strings.Contains(req.URL.Path, oAuthURI) { // this condition is here only because of tests to work + if forwardedPath := req.Header.Get("X-Forwarded-Uri"); forwardedPath != "" { + req.URL.Path = forwardedPath + req.URL.RawPath = forwardedPath + } + if forwardedMethod := req.Header.Get("X-Forwarded-Method"); forwardedMethod != "" { + req.Method = forwardedMethod + } + } + next.ServeHTTP(wrt, req) + }) + } +} diff --git a/pkg/testsuite/server_test.go b/pkg/testsuite/server_test.go index 8f193b11..70d7cd86 100644 --- a/pkg/testsuite/server_test.go +++ b/pkg/testsuite/server_test.go @@ -1354,6 +1354,7 @@ func TestNoProxy(t *testing.T) { ExpectedContent: func(body string, testNum int) { assert.Equal(t, "", body) }, + ExpectedLocation: "https://thiswillbereplaced/oauth", Headers: map[string]string{ "X-Forwarded-Host": "thiswillbereplaced", "X-Forwarded-Proto": "https", @@ -1394,10 +1395,15 @@ func TestNoProxy(t *testing.T) { { Name: "TestNoProxyWithRedirectsPrivateAuthenticated", ProxySettings: func(c *config.Config) { - c.EnableDefaultDeny = true + c.EnableDefaultDeny = false c.NoRedirects = false c.NoProxy = true c.Resources = []*authorization.Resource{ + { + URL: "/*", + Methods: utils.AllHTTPMethods, + Roles: []string{"user"}, + }, { URL: "/public/*", Methods: utils.AllHTTPMethods, @@ -1405,13 +1411,16 @@ func TestNoProxy(t *testing.T) { }, { URL: "/private", - Methods: []string{"GET"}, + Methods: []string{"POST"}, }, } }, ExecutionSettings: []fakeRequest{ { - URI: "/private", + // forward-auth will send / as path always so we are simulating it + // real path will be sent in X-Forwarded-Uri, which should be + // injected to request path in forward-auth middleware + URI: "/", ExpectedProxy: false, HasLogin: true, LoginXforwarded: true, @@ -1420,6 +1429,25 @@ func TestNoProxy(t *testing.T) { ExpectedContent: func(body string, testNum int) { assert.Equal(t, "", body) }, + Headers: map[string]string{ + "X-Forwarded-Uri": "/private", + "X-Forwarded-Method": "POST", + }, + }, + { + URI: "/", + ExpectedProxy: false, + HasLogin: true, + LoginXforwarded: true, + Redirects: true, + ExpectedCode: http.StatusForbidden, + ExpectedContent: func(body string, testNum int) { + assert.Equal(t, "", body) + }, + Headers: map[string]string{ + "X-Forwarded-Uri": "/private", + "X-Forwarded-Method": "DELETE", + }, }, }, },