Hi,
enclosed you will find an attached changeset, that allows more than one authentication challenge - multiple authenticate response-header [rfc2616 sec14.47]. Implemented for auth_request and http upstream (ex. backends). If you want to support it in your own authentication module, just call `ngx_http_upstream_transmit_headers` after setting `headers_out.www_authenticate` of request, like in both implemented modules (see changeset attached). For upstreams simply add a multiple header entries with www-authentificate challenges, supported from your module. PS. If someone needs a git version of it: https://github.com/sebres/nginx/commits/hg-sb-mod [1] Regards, sebres. Links: ------ [1] https://github.com/sebres/nginx/commits/hg-sb-mod
# HG changeset patch # User Serg G. Brester (sebres) <serg.bres...@sebres.de> # Date 1430300326 -7200 # Wed Apr 29 11:38:46 2015 +0200 # Node ID 10c2a7b3420bc03fc31b969a07daa3f354676a0e # Parent 43135346275c76add5bf953024a3d244f04184ba Allow more than one challenge - multiple authenticate response-header [rfc2616 sec14.47]: currently implemented for auth_request (and upstream) only; Header example: WWW-Authenticate: NTLM WWW-Authenticate: Digest realm="...", qop="", nonce="", opaque="" WWW-Authenticate: Basic realm="..." diff -r 43135346275c -r 10c2a7b3420b src/http/modules/ngx_http_auth_request_module.c --- a/src/http/modules/ngx_http_auth_request_module.c Tue Apr 28 15:34:33 2015 +0200 +++ b/src/http/modules/ngx_http_auth_request_module.c Wed Apr 29 11:38:46 2015 +0200 @@ -156,6 +156,16 @@ ngx_http_auth_request_handler(ngx_http_r *ho = *h; r->headers_out.www_authenticate = ho; + + /* transmit all authenticate headers (ex: multiple authenticate + * challenges [rfc2616 sec14.47]): */ + if (ngx_http_upstream_transmit_headers(r, !sr->upstream ? + &r->headers_in.headers.part : + &sr->upstream->headers_in.headers.part, + ho) != NGX_OK) + { + return NGX_ERROR; + } } return ctx->status; diff -r 43135346275c -r 10c2a7b3420b src/http/ngx_http_upstream.c --- a/src/http/ngx_http_upstream.c Tue Apr 28 15:34:33 2015 +0200 +++ b/src/http/ngx_http_upstream.c Wed Apr 29 11:38:46 2015 +0200 @@ -2293,6 +2293,57 @@ ngx_http_upstream_test_next(ngx_http_req } +ngx_int_t +ngx_http_upstream_transmit_headers(ngx_http_request_t *r, + ngx_list_part_t *part, ngx_table_elt_t *filter) +{ + ngx_table_elt_t *h, *ho; + ngx_uint_t i; + h = part->elts; + + for (i = 0; /* void */; i++) { + + if (i >= part->nelts) { + if (part->next == NULL) { + break; + } + part = part->next; + h = part->elts; + i = 0; + } + if (h[i].hash == 0) { + continue; + } + /* filter same header: */ + if (&h[i] == filter) { + continue; + } + /* filter by key name: */ + if (h[i].key.len != filter->key.len || + ngx_strncasecmp(h[i].key.data, filter->key.data, + filter->key.len) != 0) + { + continue; + } + /* filter same value: */ + if (h[i].value.len == filter->value.len && + ngx_strncasecmp(h[i].value.data, filter->value.data, + filter->value.len) == 0) + { + continue; + } + ho = ngx_list_push(&r->headers_out.headers); + if (ho == NULL) { + return NGX_ERROR; + } + + *ho = h[i]; + } + + return NGX_OK; +} + + static ngx_int_t ngx_http_upstream_intercept_errors(ngx_http_request_t *r, ngx_http_upstream_t *u) @@ -2339,6 +2390,16 @@ ngx_http_upstream_intercept_errors(ngx_h *h = *u->headers_in.www_authenticate; r->headers_out.www_authenticate = h; + + /* transmit all authenticate headers (ex: multiple authenticate + * challenges [rfc2616 sec14.47]): */ + if (ngx_http_upstream_transmit_headers(r, + &u->headers_in.headers.part, h) != NGX_OK) + { + ngx_http_upstream_finalize_request(r, u, + NGX_HTTP_INTERNAL_SERVER_ERROR); + return NGX_OK; + } } #if (NGX_HTTP_CACHE) diff -r 43135346275c -r 10c2a7b3420b src/http/ngx_http_upstream.h --- a/src/http/ngx_http_upstream.h Tue Apr 28 15:34:33 2015 +0200 +++ b/src/http/ngx_http_upstream.h Wed Apr 29 11:38:46 2015 +0200 @@ -404,6 +404,8 @@ ngx_int_t ngx_http_upstream_hide_headers ngx_http_upstream_conf_t *conf, ngx_http_upstream_conf_t *prev, ngx_str_t *default_hide_headers, ngx_hash_init_t *hash); +ngx_int_t ngx_http_upstream_transmit_headers(ngx_http_request_t *r, + ngx_list_part_t *part, ngx_table_elt_t *filter); #define ngx_http_conf_upstream_srv_conf(uscf, module) \ uscf->srv_conf[module.ctx_index]
_______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel