Verifying Signed Requests #2697
-
I'm trying to learn Rust & Rocket by building a web server that listens to webhook notifications. Before processing requests I need to verify that they have been is signed by the server by doing the following:
If the request isn't signed it should respond with http status 401 Unauthorized. I want to perform this check outside of the handler so that it is reusable across handlers at different endpoints. My initial thinking was to use fairing since the Next I looked at adding a request guard. When implementing the FromRequest trait you cannot access the payload data to perform the hashing. Finally I saw that a data guard exists. I can implement FromData which has access to the request headers, content and the ability to reject the request. I considered wrapping the expected body type in a struct that checks the signature in it FromData implementation. Here's the outline of my best approach so far (that doesn't compile): pub struct Verified<T>(pub T);
#[rocket::async_trait]
impl<'r, T: FromData<'r>> FromData<'r> for Verified<T> {
async fn from_data(req: &'r Request<'_>, data: Data<'r>) -> data::Outcome<'r, Self> {
// Check the signature here ...
// Defer to the FromData implementation of T
T::from_data(req, data).await
}
}
// Elsewhere ...
#[post("/webhook", data = "<notification>")]
async fn webhook(
notification: Verified<Json<OrderCreateNotification>>,
pool: &State<Pool<RabbitConnectionManager>>,
queue: &State<Queue>,
) -> Result<status::Accepted<String>, status::Custom<String>> {
todo!();
} This seems a bit finicky, as Is there a better approach that allows me to check all requests to an endpoint are signed before handling them? Thanks in advance |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
This just recently became possible to do efficiently in b3abc76. See #775 for more. |
Beta Was this translation helpful? Give feedback.
This just recently became possible to do efficiently in b3abc76. See #775 for more.