From cecc63bf29ff3ce5f93cfca13e92428f80670ca9 Mon Sep 17 00:00:00 2001 From: Leandro Lafin Date: Fri, 12 Jul 2024 11:42:11 -0300 Subject: [PATCH] Improve the Nginx auth_request example --- CHANGELOG.md | 1 + .../docker-compose-nginx.yaml | 1 + contrib/local-environment/nginx.conf | 2 + .../local-environment/oauth2-proxy-nginx.cfg | 2 + oauthproxy_test.go | 98 +++++++++++++++++++ 5 files changed, 104 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cd5080a9..e975c82a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - [#2237](https://github.com/oauth2-proxy/oauth2-proxy/pull/2237) adds an option to append CA certificates (@emsixteeen) - [#2128](https://github.com/oauth2-proxy/oauth2-proxy/pull/2128) Update dependencies (@vllvll) - [#2274](https://github.com/oauth2-proxy/oauth2-proxy/pull/2274) Upgrade golang.org/x/net to v0.17.0 (@pierluigilenoci) +- [#2278](https://github.com/oauth2-proxy/oauth2-proxy/pull/2278) Improve the Nginx auth_request example (@akunzai) - [#2282](https://github.com/oauth2-proxy/oauth2-proxy/pull/2282) Fixed checking Google Groups membership using Google Application Credentials (@kvanzuijlen) - [#2183](https://github.com/oauth2-proxy/oauth2-proxy/pull/2183) Allowing relative redirect url though an option - [#1866](https://github.com/oauth2-proxy/oauth2-proxy/pull/1866) Add support for unix socker as upstream (@babs) diff --git a/contrib/local-environment/docker-compose-nginx.yaml b/contrib/local-environment/docker-compose-nginx.yaml index af6c587b..582cd720 100644 --- a/contrib/local-environment/docker-compose-nginx.yaml +++ b/contrib/local-environment/docker-compose-nginx.yaml @@ -31,6 +31,7 @@ services: nginx: container_name: nginx image: nginx:1.18 + restart: unless-stopped ports: - 80:80/tcp hostname: nginx diff --git a/contrib/local-environment/nginx.conf b/contrib/local-environment/nginx.conf index 877c213e..42fc06e3 100644 --- a/contrib/local-environment/nginx.conf +++ b/contrib/local-environment/nginx.conf @@ -38,6 +38,7 @@ server { # Make sure the OAuth2 Proxy knows where the original request came from. proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Uri $request_uri; proxy_pass http://oauth2-proxy:4180/; } @@ -78,6 +79,7 @@ server { # Make sure the OAuth2 Proxy knows where the original request came from. proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-Uri $request_uri; proxy_pass http://oauth2-proxy:4180/; } diff --git a/contrib/local-environment/oauth2-proxy-nginx.cfg b/contrib/local-environment/oauth2-proxy-nginx.cfg index 2258cce0..c60c3ac2 100644 --- a/contrib/local-environment/oauth2-proxy-nginx.cfg +++ b/contrib/local-environment/oauth2-proxy-nginx.cfg @@ -10,3 +10,5 @@ cookie_secure="false" redirect_url="http://oauth2-proxy.oauth2-proxy.localhost/oauth2/callback" cookie_domains=".oauth2-proxy.localhost" # Required so cookie can be read on all subdomains. whitelist_domains=".oauth2-proxy.localhost" # Required to allow redirection back to original requested target. +# Enables the use of `X-Forwarded-*` headers to determine request correctly +reverse_proxy="true" diff --git a/oauthproxy_test.go b/oauthproxy_test.go index 42c5b3db..a27db6e2 100644 --- a/oauthproxy_test.go +++ b/oauthproxy_test.go @@ -2632,6 +2632,104 @@ func TestAllowedRequest(t *testing.T) { } } +func TestAllowedRequestWithForwardedUriHeader(t *testing.T) { + upstreamServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(200) + })) + t.Cleanup(upstreamServer.Close) + + opts := baseTestOptions() + opts.ReverseProxy = true + opts.UpstreamServers = options.UpstreamConfig{ + Upstreams: []options.Upstream{ + { + ID: upstreamServer.URL, + Path: "/", + URI: upstreamServer.URL, + }, + }, + } + opts.SkipAuthRegex = []string{ + "^/skip/auth/regex$", + } + opts.SkipAuthRoutes = []string{ + "GET=^/skip/auth/routes/get", + } + err := validation.Validate(opts) + assert.NoError(t, err) + proxy, err := NewOAuthProxy(opts, func(_ string) bool { return true }) + if err != nil { + t.Fatal(err) + } + + testCases := []struct { + name string + method string + url string + allowed bool + }{ + { + name: "Regex GET allowed", + method: "GET", + url: "/skip/auth/regex", + allowed: true, + }, + { + name: "Regex POST allowed ", + method: "POST", + url: "/skip/auth/regex", + allowed: true, + }, + { + name: "Regex denied", + method: "GET", + url: "/wrong/denied", + allowed: false, + }, + { + name: "Route allowed", + method: "GET", + url: "/skip/auth/routes/get", + allowed: true, + }, + { + name: "Route denied with wrong method", + method: "PATCH", + url: "/skip/auth/routes/get", + allowed: false, + }, + { + name: "Route denied with wrong path", + method: "GET", + url: "/skip/auth/routes/wrong/path", + allowed: false, + }, + { + name: "Route denied with wrong path and method", + method: "POST", + url: "/skip/auth/routes/wrong/path", + allowed: false, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + req, err := http.NewRequest(tc.method, opts.ProxyPrefix+authOnlyPath, nil) + req.Header.Set("X-Forwarded-Uri", tc.url) + assert.NoError(t, err) + + rw := httptest.NewRecorder() + proxy.ServeHTTP(rw, req) + + if tc.allowed { + assert.Equal(t, 202, rw.Code) + } else { + assert.Equal(t, 401, rw.Code) + } + }) + } +} + func TestAllowedRequestNegateWithoutMethod(t *testing.T) { upstreamServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200)