Hello, I try to use vouch-proxy and varnish (v7) together to build a authorisation proxy. vouch-proxy is written to work with nginx ngx_http_auth_request_module
https://github.com/vouch/vouch-proxy https://nginx.org/en/docs/http/ngx_http_auth_request_module.html Idea: inspired from https://web.archive.org/web/20121124064818/https://adayinthelifeof.nl/2012/07/06/using-varnish-to-offload-and-cache-your-oauth-requests/ - use varnish request restart feature - intercept original client request and make a GET request to vouch-proxy validate endpoint - when validated restore the original request and do a restart in detail: # vcl_recv # restarts == 0 # save req method, url, Content-Length, Content-Type in var # method := GET # url := /validate # backend := vouch-proxy # remove Content-Length, Content-Type # restarts > 0 # check vouch-proxy headers (roles, groups) # # vcl_deliver # resp == vouch-proxy,GET,/validate,200 # restore req method, url, Content-Length, Content-Type from var # forward vouch-proxy response headers to req # restart (original) req see attached common-vouch-proxy.vcl It works for client requests without request body (GET, HEAD, …) but not for POST, PUT, …. POST, PUT run in timeouts, so I think the request body is lost in the restarted request. Why is the body gone after restart? I think it should work with the curl vmod but this is not integrated yet. Thank you very much in advance tom -- Tom Anheyer Senior Developer BerlinOnline Stadtportal GmbH & Co. KG Stefan-Heym-Platz 1 10365 Berlin Germany Tel.: +49 30 2327-5210 Fax: +49 30 5771180-95 E-Mail: [email protected] berlin.de | berlinonline.net Amtsgericht Berlin-Charlottenburg, HRA 31951 Sitz der Gesellschaft: Berlin, Deutschland USt-IdNr.: DE219483549 Persönlich haftender Gesellschafter: BerlinOnline Stadtportalbeteiligungsges. mbH Amtsgericht Berlin-Charlottenburg, HRB 79077 Sitz der Gesellschaft: Berlin, Deutschland Geschäftsführung: Olf Dziadek, Andreas Mängel Amtierender Vorsitzender des Aufsichtsrates: Lothar Sattler
# # authorisisation proxy using vouch-proxy # # Idea: # # vcl_recv # restarts == 0 # save client req method, url, Content-Length, Content-Type in var # method := GET # url := /validate # backend := vouch-proxy # remove Content-Length, Content-Type # restarts > 0 # check vouch-proxy headers (roles, groups) # # vcl_deliver # resp == vouch-proxy,GET,/validate,200 # restore req method, url, Content-Length, Content-Type from var # forward vouch-proxy response headers to req # restart (client) req # # Links: # - https://web.archive.org/web/20121124064818/https://adayinthelifeof.nl/2012/07/06/using-varnish-to-offload-and-cache-your-oauth-requests/ # - https://github.com/vouch/vouch-proxy # - https://nginx.org/en/docs/http/ngx_http_auth_request_module.html # # Usage: # in vcl_recv # # var.set_backend("vouch_proxy", â¦); # # call vouch_proxy_auth; # if (req.http.X-Vouch-Claims-Roles !~ {""â¦""}) { # # missing role # return(synth(403, "Forbidden")); # } sub choose_vouch_proxy { if (req.http.host ~ "^vouch.") { set req.backend_hint = var.get_backend("vouch_proxy"); return(pass); } } sub vouch_proxy_auth { if (req.restarts == 0 && var.get_backend("vouch_proxy") != default) { # original request from external client # - remove X-Vouch-Success header to ensure header is set correctly if (req.http.X-Vouch-Success) { unset req.http.X-Vouch-Success; } # - we have to check authorisisation if (cookie.get("VouchCookie")) { # existing vouch-proxy authorisisation session # - intercept request # - send request to /validate endpoint if (! req.http.Content-Length || req.method !~ "^(?:POST|PUT|PATCH|DELETE)$") { # send validate request for all requests without body # (Workaround for POST, PUT, â¦) if (req.method != "GET") { var.set_string("req.method", req.method); set req.method = "GET"; } set req.url = "/__vouch_proxy/validate"; if (req.http.Content-Length) { var.set_string("req.http.Content-Length", req.http.Content-Length); unset req.http.Content-Length; } if (req.http.Content-Type) { var.set_string("req.http.Content-Type", req.http.Content-Type); unset req.http.Content-Type; } var.set_int("allow_cache_with_cookie", 1); set req.backend_hint = var.get_backend("vouch_proxy"); return(hash); } } else { # missing authorisisation session # - redirect to OIDC login return(synth(308, var.get_string("vouch_vhost") + "/__vouch_proxy/login?url=https://" + req.http.X-Portal + req.http.X-Url)); } } } sub vcl_recv { if (false) { call choose_vouch_proxy; call vouch_proxy_auth; } } sub vcl_hash { if (req.url == "/__vouch_proxy/validate") { # hash the OIDC validation request for current user hash_data(req.http.host); hash_data(req.url); hash_data(cookie.get("VouchCookie")); hash_data(client.identity); return (lookup); } } sub vcl_backend_response { if (bereq.url ~ "^/__vouch_proxy" && beresp.status != 200) { # negative TTL for failed requests set beresp.ttl = 5s; } } sub vcl_deliver { if (req.restarts == 0 && req.url == "/__vouch_proxy/validate") { if (resp.status == 200) { if (var.get_string("req.method")) { set req.method = var.get_string("req.method"); } set req.url = req.http.X-Url; if (req.http.host != req.http.X-Portal) { set req.http.host = req.http.X-Portal; } if (var.get_string("req.http.Content-Type")) { set req.http.Content-Type = var.get_string("req.http.Content-Type"); } if (var.get_string("req.http.Content-Length")) { set req.http.Content-Length = var.get_string("req.http.Content-Length"); } # # forward vouch validate response headers to application backend request # if (resp.http.X-Vouch-User) { set req.http.X-Vouch-User = resp.http.X-Vouch-User; } if (resp.http.X-Vouch-Success) { set req.http.X-Vouch-Success = resp.http.X-Vouch-Success; } if (resp.http.X-Vouch-Claims-Groups) { set req.http.X-Vouch-Claims-Groups = resp.http.X-Vouch-Claims-Groups; } if (resp.http.X-Vouch-Claims-Locale) { set req.http.X-Vouch-Claims-Locale = resp.http.X-Vouch-Claims-Locale; } if (resp.http.X-Vouch-Claims-Preferred-Username) { set req.http.X-Vouch-Claims-Preferred-Username = resp.http.X-Vouch-Claims-Preferred-Username; } if (resp.http.X-Vouch-Claims-Roles) { set req.http.X-Vouch-Claims-Roles = resp.http.X-Vouch-Claims-Roles; } return(restart); } else { return(synth(308, var.get_string("vouch_vhost") + "/__vouch_proxy/login?url=https://" + req.http.X-Portal + req.http.X-Url)); } } }
_______________________________________________ varnish-misc mailing list [email protected] https://www.varnish-cache.org/lists/mailman/listinfo/varnish-misc
