mirror of
https://github.com/apache/httpd.git
synced 2026-10-23 22:49:01 +03:00
mod_auth_digest: Send Digest domain= for a reverse-proxied request:
The domain was suppressed for any proxy request, but a reverse-proxied request authenticates to this server with an origin-style WWW-Authenticate, so AuthDigestDomain applies to it as it does to a non-proxied request; only a forward-proxy (PROXYREQ_PROXY) request, whose challenge is Proxy-Authenticate, should omit it. * modules/aaa/mod_auth_digest.c (note_digest_auth_failure): Suppress domain= only for PROXYREQ_PROXY, matching the rest of the file. * test/modules/aaa/env.py: Load mod_proxy and mod_proxy_http. * test/modules/aaa/conftest.py: Add a reverse-proxied location which authenticates with Digest and sets AuthDigestDomain. * test/modules/aaa/test_013_proxy_domain.py: New test suite. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> GitHub: PR #787 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1939035 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
@@ -1302,7 +1302,7 @@ static int note_digest_auth_failure(request_rec *r,
|
||||
/* Setup domain, which tells the client which URIs share this
|
||||
* protection space, so that it does not send the Authorization header
|
||||
* (usually more than 200 bytes) where it is not needed. */
|
||||
if (r->proxyreq || !conf->uri_list) {
|
||||
if (r->proxyreq == PROXYREQ_PROXY || !conf->uri_list) {
|
||||
domain = NULL;
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -99,6 +99,21 @@ def env(pytestconfig) -> AAATestEnv:
|
||||
# has no per-request Digest record; an ErrorDocument redirecting it into
|
||||
# a Digest-protected location must not then dereference that record.
|
||||
conf.add('ErrorDocument 400 /digest/default/secret.txt')
|
||||
# A reverse-proxied location which authenticates with Digest at the
|
||||
# proxy (so the backend is never reached and need not be reachable).
|
||||
# The challenge is an origin-style WWW-Authenticate, so AuthDigestDomain
|
||||
# applies to it just as for a non-proxied location.
|
||||
conf.add([
|
||||
'ProxyPass "/pxdomain/" "http://127.0.0.1:1/unused/"',
|
||||
'<Location "/pxdomain/">',
|
||||
' AuthType Digest',
|
||||
f' AuthName "{AAATestEnv.REALM}"',
|
||||
' AuthDigestProvider file',
|
||||
f' AuthUserFile "{pwfile}"',
|
||||
' AuthDigestDomain "/pxdomain/"',
|
||||
' Require valid-user',
|
||||
'</Location>',
|
||||
])
|
||||
conf.install()
|
||||
assert env.apache_restart() == 0
|
||||
return env
|
||||
|
||||
@@ -16,7 +16,7 @@ class AAATestSetup(HttpdTestSetup):
|
||||
super().__init__(env=env)
|
||||
self.add_source_dir(os.path.dirname(inspect.getfile(AAATestSetup)))
|
||||
self.add_modules(["auth_digest", "authn_file", "authn_core",
|
||||
"authz_core", "authz_user"])
|
||||
"authz_core", "authz_user", "proxy", "proxy_http"])
|
||||
|
||||
|
||||
class AAATestEnv(HttpdTestEnv):
|
||||
|
||||
25
test/modules/aaa/test_013_proxy_domain.py
Normal file
25
test/modules/aaa/test_013_proxy_domain.py
Normal file
@@ -0,0 +1,25 @@
|
||||
"""AuthDigestDomain on a reverse-proxied location.
|
||||
|
||||
Digest auth can run at a reverse proxy, for a location mapped by ProxyPass.
|
||||
Such a request carries PROXYREQ_REVERSE, but its 401 is an ordinary
|
||||
origin-style WWW-Authenticate (the client authenticates to this server, not
|
||||
through it), so the configured AuthDigestDomain belongs in the challenge
|
||||
just as for a non-proxied location.
|
||||
|
||||
The suppression test treated any proxy request alike and dropped domain=
|
||||
for the reverse-proxied case, so clients re-authenticated per URI prefix
|
||||
and sent the Authorization header outside the intended protection space.
|
||||
"""
|
||||
|
||||
from . import digest_client as dc
|
||||
|
||||
|
||||
class TestDigestProxyDomain:
|
||||
|
||||
def test_digest_130_domain_sent_for_reverse_proxy(self, env):
|
||||
r = env.curl_get(env.mkurl("http", "aaa", "/pxdomain/secret.txt"))
|
||||
assert r.response["status"] == 401
|
||||
challenge = dc.DigestChallenge.parse(
|
||||
r.response["header"]["www-authenticate"])
|
||||
assert "/pxdomain/" in challenge.domain_list(), \
|
||||
"AuthDigestDomain was dropped from a reverse-proxied challenge"
|
||||
Reference in New Issue
Block a user