Replies: 4 comments
-
haproxy-auth-request does not send anything to the client by itself. It just performs a sub-request and sets variables. What you do with these variable is up to you. You should be able to achieve what you need by doing something like the following:
|
Beta Was this translation helpful? Give feedback.
-
Thanks for the response @TimWolla. Not sure if I'm doing something wrong but it looked to me like whenever I perform a I initially thought this may have been because we have HAProxy performing the TLS termination for the actual auth backend but I've tried reverting to a non-tls backend for the He's my full config in case it helps: global
lua-prepend-path /usr/local/etc/haproxy/?/http.lua
lua-load /usr/local/etc/haproxy/auth-request.lua
log stdout format raw local0 debug
defaults
mode http
log global
option httplog
option forwardfor
frontend fe_api
bind *:8081 ssl crt /usr/local/etc/haproxy/haproxy.pem
stats enable
stats uri /api
stats refresh 10s
stats admin if LOCALHOST
frontend fe_http
bind *:8080 ssl crt /usr/local/etc/haproxy/haproxy.pem
acl api-path path_beg -i /api
acl headers-path path -i -m end /headers
acl host-authelia-portal hdr(host) -i login.example.com:8080
acl protected-frontends hdr(host) -m reg -i ^(?i)(admin|home|public|secure)\.example\.com
acl protected-frontends-basic hdr(host) -m reg -i ^(?i)(singlefactor)\.example\.com
http-request set-var(req.scheme) str(https) if { ssl_fc }
http-request set-var(req.scheme) str(http) if !{ ssl_fc }
http-request set-var(req.questionmark) str(?) if { query -m found }
http-request set-var(req.method) str(CONNECT) if { method CONNECT }
http-request set-var(req.method) str(GET) if { method GET }
http-request set-var(req.method) str(HEAD) if { method HEAD }
http-request set-var(req.method) str(OPTIONS) if { method OPTIONS }
http-request set-var(req.method) str(POST) if { method POST }
http-request set-var(req.method) str(TRACE) if { method TRACE }
http-request set-var(req.method) str(PUT) if { method PUT }
http-request set-var(req.method) str(PATCH) if { method PATCH }
http-request set-var(req.method) str(DELETE) if { method DELETE }
http-request set-header X-Forwarded-Method %[var(req.method)]
http-request set-header X-Real-IP %[src]
http-request set-header X-Forwarded-Proto %[var(req.scheme)]
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
http-request set-header X-Forwarded-Uri %[path]%[var(req.questionmark)]%[query]
# be_auth_request is used to make HAProxy do the TLS termination since the Lua script
# does not know how to handle it (see https://github.com/TimWolla/haproxy-auth-request/issues/12).
http-request lua.auth-request be_auth_request /api/verify if protected-frontends
http-request lua.auth-request be_auth_request /api/verify?auth=basic if protected-frontends-basic
http-request set-var(txn.auth) var(req.auth_response_header.www_authenticate) if protected-frontends-basic !{ var(txn.auth_response_successful) -m bool }
http-response set-header WWW-Authenticate %[var(txn.auth)] if !{ var(txn.auth_response_successful) -m bool }
http-request redirect location https://login.example.com:8080/?rd=%[var(req.scheme)]://%[base]%[var(req.questionmark)]%[query] if protected-frontends !{ var(txn.auth_response_successful) -m bool }
http-request deny deny_status 401 if protected-frontends-basic !{ var(txn.auth_response_successful) -m bool }
use_backend be_authelia if host-authelia-portal api-path
use_backend fe_authelia if host-authelia-portal !api-path
use_backend be_httpbin if protected-frontends headers-path
use_backend be_mail if { hdr(host) -i mail.example.com:8080 }
use_backend be_protected if protected-frontends || protected-frontends-basic
backend be_auth_request
mode http
server proxy 127.0.0.1:8085
listen be_auth_request_proxy
mode http
bind 127.0.0.1:8085
server authelia-backend authelia-backend:9091 ssl verify none
backend be_authelia
server authelia-backend authelia-backend:9091 ssl verify none
backend fe_authelia
server authelia-frontend authelia-frontend:3000
backend be_httpbin
acl remote_user_exist var(req.auth_response_header.remote_user) -m found
acl remote_groups_exist var(req.auth_response_header.remote_groups) -m found
acl remote_name_exist var(req.auth_response_header.remote_name) -m found
acl remote_email_exist var(req.auth_response_header.remote_email) -m found
http-request set-header Remote-User %[var(req.auth_response_header.remote_user)] if remote_user_exist
http-request set-header Remote-Groups %[var(req.auth_response_header.remote_groups)] if remote_groups_exist
http-request set-header Remote-Name %[var(req.auth_response_header.remote_name)] if remote_name_exist
http-request set-header Remote-Email %[var(req.auth_response_header.remote_email)] if remote_email_exist
server httpbin-backend httpbin:8000
backend be_mail
server smtp-backend smtp:1080
backend be_protected
server nginx-backend nginx-backend:80 Ideally what I'm trying to achieve with this flow is if the auth request backend responds with a 401 and the WWW-Authenticate header that this illicits the same response to the client. If I remove the If I add the |
Beta Was this translation helpful? Give feedback.
-
This is a HAProxy limitation. The |
Beta Was this translation helpful? Give feedback.
-
Thanks for your support @TimWolla I've managed to get this working as expected. |
Beta Was this translation helpful? Give feedback.
-
Would it be possible to to ensure that the client also receives the
WWW-Authenticate
header from the subrequest response if a 401 is returned similar to ngx_http_auth_request_module?This should ensure that if basic auth is being requested the appropriate prompt will be presented to the client.
Beta Was this translation helpful? Give feedback.
All reactions