Crate http_signature_normalization_actix[−][src]
Integration of Http Signature Normalization with Actix Web
This library provides middlewares for verifying HTTP Signature headers and, optionally, Digest
headers with the digest
feature enabled. It also extends actix_web's ClientRequest type to
add signatures and digests to the request
Use it in a server
use actix_web::{http::StatusCode, web, App, HttpResponse, HttpServer, ResponseError}; use futures::future::{err, ok, Ready}; use http_signature_normalization_actix::prelude::*; use sha2::{Digest, Sha256}; #[derive(Clone, Debug)] struct MyVerify; impl SignatureVerify for MyVerify { type Error = MyError; type Future = Ready<Result<bool, Self::Error>>; fn signature_verify( &mut self, algorithm: Option<Algorithm>, key_id: String, signature: String, signing_string: String, ) -> Self::Future { match algorithm { Some(Algorithm::Hs2019) => (), _ => return err(MyError::Algorithm), }; if key_id != "my-key-id" { return err(MyError::Key); } let decoded = match base64::decode(&signature) { Ok(decoded) => decoded, Err(_) => return err(MyError::Decode), }; ok(decoded == signing_string.as_bytes()) } } async fn index((_, sig_verified): (DigestVerified, SignatureVerified)) -> &'static str { println!("Signature verified for {}", sig_verified.key_id()); "Eyyyyup" } #[actix_rt::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let config = Config::default(); HttpServer::new(move || { App::new() .wrap(VerifyDigest::new(Sha256::new()).optional()) .wrap( VerifySignature::new(MyVerify, config.clone()) .authorization() .optional(), ) .route("/", web::post().to(index)) }) .bind("127.0.0.1:8010")? .run() .await?; Ok(()) } #[derive(Debug, thiserror::Error)] enum MyError { #[error("Failed to verify, {}", _0)] Verify(#[from] PrepareVerifyError), #[error("Unsupported algorithm")] Algorithm, #[error("Couldn't decode signature")] Decode, #[error("Invalid key")] Key, } impl ResponseError for MyError { fn status_code(&self) -> StatusCode { StatusCode::BAD_REQUEST } fn error_response(&self) -> HttpResponse { HttpResponse::BadRequest().finish() } }
Use it in a client
use actix_web::{client::Client, error::BlockingError}; use http_signature_normalization_actix::prelude::*; use sha2::{Digest, Sha256}; #[actix_rt::main] async fn main() -> Result<(), Box<dyn std::error::Error>> { let config = Config::default(); let digest = Sha256::new(); let mut response = Client::default() .post("http://127.0.0.1:8010/") .header("User-Agent", "Actix Web") .set(actix_web::http::header::Date(SystemTime::now().into())) .signature_with_digest(config, "my-key-id", digest, "Hewwo-owo", |s| { println!("Signing String\n{}", s); Ok(base64::encode(s)) as Result<_, MyError> }) .await? .send() .await .map_err(|e| { eprintln!("Error, {}", e); MyError::SendRequest })?; let body = response.body().await.map_err(|e| { eprintln!("Error, {}", e); MyError::Body })?; println!("{:?}", body); Ok(()) } #[derive(Debug, thiserror::Error)] pub enum MyError { #[error("Failed to create signing string, {0}")] Convert(#[from] PrepareSignError), #[error("Failed to create header, {0}")] Header(#[from] InvalidHeaderValue), #[error("Failed to send request")] SendRequest, #[error("Failed to retrieve request body")] Body, #[error("Blocking operation was canceled")] Canceled, } impl From<BlockingError> for MyError { fn from(_: BlockingError) -> Self { MyError::Canceled, } }
Modules
create | Types for signing requests with Actix Web |
digest | Types and Traits for creating and verifying Digest headers |
middleware | Types for verifying requests with Actix Web |
prelude | Useful types and traits for using this library in Actix Web |
verify | Types for Verifying an HTTP Signature |
Structs
Config | Configuration for signing and verifying signatures |
RequiredError | Failed to build a signing string due to missing required headers |
Enums
PrepareSignError | An error when preparing to sign a request |
PrepareVerifyError | An error when preparing to verify a request |
Traits
Sign | A trait implemented by the Actix Web ClientRequest type to add an HTTP signature to the request |
SignatureVerify | A trait for verifying signatures |