Available on crate feature
auth only.Expand description
Forward-auth middleware — delegates the allow/deny decision for every
request to an external HTTP service (Traefik’s forwardAuth, nginx’s
auth_request), so a policy engine (OPA, Casbin) or a centralized auth
service can gate requests without embedding that logic in rws.
No new dependency: makes a plain GET via the existing outbound
crate::http_client::Client.
§Example
use rust_web_server::app::App;
use rust_web_server::core::New;
use rust_web_server::auth::forward::ForwardAuthLayer;
let app = App::new()
.wrap(ForwardAuthLayer::new("http://auth.internal/verify")
.copy_header("X-User-Id")
.copy_header("X-Roles")
.timeout_ms(2000));§How it works
- Every incoming request header is copied onto a
GETrequest sent to the configured auth service URL. - 2xx response — the request is allowed through. Any header named in
.copy_header(...)that’s present on the auth service’s response replaces (not appends to — see below) the same-named header on the forwarded request. This is how an auth service that resolves a session cookie to a user ID hands that ID to your handler as a plain header. - Any other status — the auth service’s response is returned to the
client verbatim: status code, all headers (except hop-by-hop and
body-framing ones), and body. This preserves
WWW-Authenticatechallenges,Locationredirects for OAuth flows, and custom error bodies without rws needing to understand any of them. - Auth service unreachable (connection refused, timeout, DNS
failure) — the request is rejected with
502 Bad Gateway. This fails closed: an unreachable auth service is not the same as “access granted.”
Copied headers replace any same-named header the client already sent,
rather than being appended alongside it — otherwise a client could send
its own X-User-Id and have it coexist with (and potentially shadow) the
auth service’s verified value, depending on which duplicate a downstream
get_header call happens to match first.
Structs§
- Forward
Auth Layer - Middleware that delegates the allow/deny decision for every request to an external HTTP service. See the module docs for the full flow.