1
0
mirror of https://github.com/oauth2-proxy/oauth2-proxy.git synced 2025-03-17 21:17:53 +02:00

Improve the Nginx auth_request example (#2278)

* The `X-Forwarded-Uri` was required to bypass authentication

- Fix the `skip_auth_routes` option not working in Nginx

* Add tests for allowed requests with proxied `X-Forwarded-Uri` header

* Avoid nginx startup failure: host not found in upstream "oauth2-proxy"

* The `--reverse-proxy` option is required for nginx

* Update the change logs

* Use the authOnlyPath constant

* Remove the unused header `X-Scheme`
This commit is contained in:
Charley Wu 2023-11-03 06:57:21 +08:00 committed by GitHub
parent 66bfd8ebd5
commit 5e8956b52f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 107 additions and 3 deletions

View File

@ -13,6 +13,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)

View File

@ -31,6 +31,7 @@ services:
nginx:
container_name: nginx
image: nginx:1.18
restart: unless-stopped
ports:
- 80:80/tcp
hostname: nginx

View File

@ -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/;
}

View File

@ -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"

View File

@ -339,6 +339,8 @@ Available variables for standard logging:
## Configuring for use with the Nginx `auth_request` directive
**This option requires `--reverse-proxy` option to be set.**
The [Nginx `auth_request` directive](http://nginx.org/en/docs/http/ngx_http_auth_request_module.html) allows Nginx to authenticate requests via the oauth2-proxy's `/auth` endpoint, which only returns a 202 Accepted response or a 401 Unauthorized response without proxying the request through. For example:
```nginx
@ -351,7 +353,6 @@ server {
proxy_pass http://127.0.0.1:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Auth-Request-Redirect $request_uri;
# or, if you are handling multiple domains:
# proxy_set_header X-Auth-Request-Redirect $scheme://$host$request_uri;
@ -360,7 +361,7 @@ server {
proxy_pass http://127.0.0.1:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_set_header X-Forwarded-Uri $request_uri;
# nginx auth_request includes headers but not body
proxy_set_header Content-Length "";
proxy_pass_request_body off;

View File

@ -63,7 +63,6 @@ There are two recommended configurations:
proxy_pass http://127.0.0.1:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_connect_timeout 1;
proxy_send_timeout 30;
proxy_read_timeout 30;

View File

@ -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)