Skip to content

Commit 22d606b

Browse files
committed
feat: support rewritten paths for auth handling
1 parent ff12fe3 commit 22d606b

3 files changed

Lines changed: 23 additions & 3 deletions

File tree

crates/core/src/proxy.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,7 @@ where
268268
req.query,
269269
req.headers,
270270
req.source_ip,
271+
req.signing_path,
271272
)
272273
.await;
273274

@@ -362,7 +363,7 @@ where
362363
source_ip: Option<IpAddr>,
363364
) -> HandlerAction {
364365
let (action, _metadata) = self
365-
.resolve_request_with_metadata(method, path, query, headers, source_ip)
366+
.resolve_request_with_metadata(method, path, query, headers, source_ip, None)
366367
.await;
367368
action
368369
}
@@ -376,6 +377,7 @@ where
376377
query: Option<&str>,
377378
headers: &HeaderMap,
378379
source_ip: Option<IpAddr>,
380+
signing_path: Option<&str>,
379381
) -> (HandlerAction, RequestMetadata) {
380382
let request_id = Uuid::new_v4().to_string();
381383

@@ -397,10 +399,11 @@ where
397399
};
398400
tracing::debug!(operation = ?operation, "parsed S3 operation");
399401

400-
// Resolve identity
402+
// Resolve identity — use the original client-facing path for signature
403+
// verification when a signing_path is provided (e.g. path-mapping rewrites).
401404
let identity = match auth::resolve_identity(
402405
&method,
403-
path,
406+
signing_path.unwrap_or(path),
404407
query.unwrap_or(""),
405408
headers,
406409
&self.credential_registry,

crates/core/src/route_handler.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,12 @@ pub struct RequestInfo<'a> {
218218
/// Populated by the router when a route pattern matches. Empty when the
219219
/// request is constructed via [`RequestInfo::new`].
220220
pub params: Params,
221+
/// The original path as seen by the client, used for SigV4 signature
222+
/// verification when the proxy rewrites paths before dispatch.
223+
///
224+
/// When `None`, `path` is used for both operation parsing and signature
225+
/// verification.
226+
pub signing_path: Option<&'a str>,
221227
}
222228

223229
impl<'a> RequestInfo<'a> {
@@ -236,8 +242,18 @@ impl<'a> RequestInfo<'a> {
236242
headers,
237243
source_ip,
238244
params: Params::default(),
245+
signing_path: None,
239246
}
240247
}
248+
249+
/// Set the original client-facing path for SigV4 signature verification.
250+
///
251+
/// Use this when the proxy rewrites paths (e.g. path-mapping) so that
252+
/// signature verification uses the path the client actually signed.
253+
pub fn with_signing_path(mut self, signing_path: &'a str) -> Self {
254+
self.signing_path = Some(signing_path);
255+
self
256+
}
241257
}
242258

243259
/// A pluggable handler that can intercept requests before proxy dispatch.

crates/core/src/router.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ impl Router {
6666
query: req.query,
6767
headers: req.headers,
6868
source_ip: req.source_ip,
69+
signing_path: req.signing_path,
6970
};
7071
matched
7172
.value

0 commit comments

Comments
 (0)