Use authorization header instead of neon-auth-token

This commit is contained in:
Erik Grinaker
2025-04-30 10:38:44 +02:00
parent b5373de208
commit 7bb58be546
3 changed files with 27 additions and 16 deletions

View File

@@ -61,7 +61,7 @@ impl PageserverClient {
_auth_token: auth_token.clone(),
shard_map,
channels: RwLock::new(HashMap::new()),
auth_interceptor: AuthInterceptor::new(tenant_id, timeline_id, auth_token.as_ref()),
auth_interceptor: AuthInterceptor::new(tenant_id, timeline_id, auth_token.as_deref()),
}
}
@@ -206,15 +206,17 @@ struct AuthInterceptor {
tenant_id: AsciiMetadataValue,
timeline_id: AsciiMetadataValue,
auth_token: Option<AsciiMetadataValue>,
auth_header: Option<AsciiMetadataValue>, // including "Bearer " prefix
}
impl AuthInterceptor {
fn new(tenant_id: &str, timeline_id: &str, auth_token: Option<&String>) -> Self {
fn new(tenant_id: &str, timeline_id: &str, auth_token: Option<&str>) -> Self {
Self {
tenant_id: tenant_id.parse().expect("could not parse tenant id"),
timeline_id: timeline_id.parse().expect("could not parse timeline id"),
auth_token: auth_token.map(|x| x.parse().expect("could not parse auth token")),
auth_header: auth_token
.map(|t| format!("Bearer {t}"))
.map(|t| t.parse().expect("could not parse auth token")),
}
}
}
@@ -225,9 +227,9 @@ impl tonic::service::Interceptor for AuthInterceptor {
.insert("neon-tenant-id", self.tenant_id.clone());
req.metadata_mut()
.insert("neon-timeline-id", self.timeline_id.clone());
if let Some(auth_token) = &self.auth_token {
if let Some(auth_header) = &self.auth_header {
req.metadata_mut()
.insert("neon-auth-token", auth_token.clone());
.insert("authorization", auth_header.clone());
}
Ok(req)

View File

@@ -1,9 +1,9 @@
// Page service presented by pageservers, for computes.
//
// Each request must come with the following metadata:
// - neon-tenant-id
// - neon-timeline-id
// - neon-auth-token (if auth is enabled)
// Request metadata:
// - authorization: JWT token ("Bearer <token>"), if auth is enabled
// - neon-tenant-id: tenant ID ("7c4a1f9e3bd6470c8f3e21a65bd2e980")
// - neon-timeline-id: timeline ID ("f08c4e9a2d5f76b1e3a7c2d8910f4b3e")
//
// TODO: what else? Priority? OpenTelemetry tracing?
//

View File

@@ -722,13 +722,22 @@ impl tonic::service::Interceptor for PageServiceAuthenticator {
return Ok(req);
};
let jwt = req
let authorization = req
.metadata()
.get("neon-auth-token")
.ok_or(tonic::Status::unauthenticated("no neon-auth-token"))?;
let jwt = jwt.to_str().map_err(|_| {
tonic::Status::invalid_argument("invalid UTF-8 characters in neon-auth-token metadata")
})?;
.get("authorization")
.ok_or(tonic::Status::unauthenticated("no authorization header"))?
.to_str()
.map_err(|_| {
tonic::Status::invalid_argument(
"invalid UTF-8 characters in authorization metadata",
)
})?;
if &authorization[0..7] != "Bearer " {
return Err(tonic::Status::unauthenticated(
"authorization header must start with 'Bearer '",
));
}
let jwt = &authorization[7..].trim();
let jwtdata: TokenData<utils::auth::Claims> = auth
.decode(jwt)