]> git.kaiwu.me - nginx.git/commitdiff
Proxy authentication for CONNECT requests
authorRoman Arutyunyan <arut@nginx.com>
Thu, 16 Apr 2026 16:57:24 +0000 (20:57 +0400)
committerRoman Arutyunyan <arutyunyan.roman@gmail.com>
Fri, 8 May 2026 05:42:58 +0000 (09:42 +0400)
Notably, ngx_http_auth_basic_module uses Proxy-Authorization input
header, Proxy-Authenticate output header and HTTP code 407 instead
of Authorization, WWW-Authenticate and 401 respectively.

src/http/modules/ngx_http_auth_basic_module.c
src/http/ngx_http_core_module.c
src/http/ngx_http_request.h

index 69e8d216118906c8696a026526d34de5f1ba5766..fd95e2eade68075019184522bf1b6afdc8570401 100644 (file)
@@ -318,11 +318,12 @@ ngx_http_auth_basic_crypt_handler(ngx_http_request_t *r, ngx_str_t *passwd,
 static ngx_int_t
 ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
 {
-    size_t   len;
-    u_char  *basic, *p;
+    size_t            len;
+    u_char           *basic, *p;
+    ngx_table_elt_t  *h;
 
-    r->headers_out.www_authenticate = ngx_list_push(&r->headers_out.headers);
-    if (r->headers_out.www_authenticate == NULL) {
+    h = ngx_list_push(&r->headers_out.headers);
+    if (h == NULL) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
@@ -330,8 +331,7 @@ ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
 
     basic = ngx_pnalloc(r->pool, len);
     if (basic == NULL) {
-        r->headers_out.www_authenticate->hash = 0;
-        r->headers_out.www_authenticate = NULL;
+        h->hash = 0;
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
@@ -339,13 +339,21 @@ ngx_http_auth_basic_set_realm(ngx_http_request_t *r, ngx_str_t *realm)
     p = ngx_cpymem(p, realm->data, realm->len);
     *p = '"';
 
-    r->headers_out.www_authenticate->hash = 1;
-    r->headers_out.www_authenticate->next = NULL;
-    ngx_str_set(&r->headers_out.www_authenticate->key, "WWW-Authenticate");
-    r->headers_out.www_authenticate->value.data = basic;
-    r->headers_out.www_authenticate->value.len = len;
+    h->hash = 1;
+    h->next = NULL;
+    h->value.data = basic;
+    h->value.len = len;
+
+    if (ngx_http_proxy_auth(r)) {
+        r->headers_out.proxy_authenticate = h;
+        ngx_str_set(&h->key, "Proxy-Authenticate");
+        return NGX_HTTP_PROXY_AUTH_REQUIRED;
 
-    return NGX_HTTP_UNAUTHORIZED;
+    } else {
+        r->headers_out.www_authenticate = h;
+        ngx_str_set(&h->key, "WWW-Authenticate");
+        return NGX_HTTP_UNAUTHORIZED;
+    }
 }
 
 
index 53ddf39bb8723bd4f085a816765a1db746aca788..4c51f7edf3ebf040cd166c609197c411be4dd113 100644 (file)
@@ -1144,7 +1144,10 @@ ngx_http_core_access_phase(ngx_http_request_t *r, ngx_http_phase_handler_t *ph)
         if (rc == NGX_OK) {
             r->access_code = 0;
 
-            for (h = r->headers_out.www_authenticate; h; h = h->next) {
+            h = ngx_http_proxy_auth(r) ? r->headers_out.proxy_authenticate
+                                       : r->headers_out.www_authenticate;
+
+            for ( /* void */ ; h; h = h->next) {
                 h->hash = 0;
             }
 
@@ -2001,19 +2004,23 @@ ngx_http_map_uri_to_path(ngx_http_request_t *r, ngx_str_t *path,
 ngx_int_t
 ngx_http_auth_basic_user(ngx_http_request_t *r)
 {
-    ngx_str_t   auth, encoded;
-    ngx_uint_t  len;
+    ngx_str_t         auth, encoded;
+    ngx_uint_t        len;
+    ngx_table_elt_t  *h;
 
     if (r->headers_in.user.len == 0 && r->headers_in.user.data != NULL) {
         return NGX_DECLINED;
     }
 
-    if (r->headers_in.authorization == NULL) {
+    h = ngx_http_proxy_auth(r) ? r->headers_in.proxy_authorization
+                               : r->headers_in.authorization;
+
+    if (h == NULL) {
         r->headers_in.user.data = (u_char *) "";
         return NGX_DECLINED;
     }
 
-    encoded = r->headers_in.authorization->value;
+    encoded = h->value;
 
     if (encoded.len < sizeof("Basic ") - 1
         || ngx_strncasecmp(encoded.data, (u_char *) "Basic ",
index 48eb43eb0ffca25b9aade93a7d87e09f4aa5cf98..6d18cc3c6cc6d7f03aa30a8b6380e19fb20d3e8b 100644 (file)
@@ -618,7 +618,9 @@ typedef struct {
 } ngx_http_ephemeral_t;
 
 
-#define ngx_http_ephemeral(r)  (void *) (&r->uri_start)
+#define ngx_http_ephemeral(r)   (void *) (&r->uri_start)
+
+#define ngx_http_proxy_auth(r)  ((r)->method == NGX_HTTP_CONNECT)
 
 
 extern ngx_http_header_t       ngx_http_headers_in[];