#![cfg(all(feature = "reqwest-blocking", feature = "jwt", feature = "step"))] use std::sync::Arc; use std::time::Duration; use authentic::credential::JsonWebTokenCredential; use authentic::reqwest::blocking::BearerAuthentication; use authentic::{AuthenticationProtocol, AuthenticationStep, WithAuthentication}; const PRIVATE_KEY: &[u8] = b"-----BEGIN RSA PRIVATE KEY----- MIIEogIBAAKCAQEAyjG6vbJV34K4IisaCs0p9BhuNPJdu/Eeq+EIRLbo3T2QVxhX ZGCeokIytyEokSa6ok5S3ippo5ZliCWjLwLIbc0jqdavT1Gn3vsF7dzz3z4R6sS8 zxxm5SwKQxF3RTz4BgiITG3RkJQ9ya3QOXHBoQYVUTin89e1goN9MB8CQO1c00J0 cSV/NtvW8KUNEHxPmT/FYR/aiYC71f7eEO3AYKsOdUqo73rt53V39rJANcY7OyhN 4HuTYu9AtpELNcE7YR02REspCnNrPYbG7G4QCrpZ4eRNA1HRW/pQfltvxh92tSmN rAkDj/a6zNFDTaXODZt0YMSs9au4WQxVAarO9wIDAQABAoIBAHpTJbgYSU2kxwOc 8e9w+h28HgiYTM8kbDruNNNlmXIoCcg3aL/ImJBv3kDepa1TMfx5yDaykCCxH5ID uzr4wwty3U2mHX+uVhJX6dljIIOCCNLw3Y2rkDC7uSWkTnUsEp2L0fHzSqLenJcE OgJW6R8jEAiIb0vdx+lC5Z0UVYezPt4lIAR8vcAjANJTbk5aVx6XcAg5AC8pl0mT SAzG36XbaPemt4tt1ZB2IoJp3z+3xLWuGYJcCvGU7qx8qHS07D3hnw1wegR8c6Lm 7DUz2BN/KMNijOzCjUhq3mVzeJsit2z/MNatqkLoLv44pnfKZHqRDM/SsZC6zLK7 pPQfZxkCgYEA8xd/HprbZK6DbaD28kAl4jQw33TjTumudx4NfPJYFytt3jbPelpy qDpqwpejPjWxIvq4eaGsxk6C0mmqbCT1wkQwcik+WyQmia/lxhjySLkz+sanLIVh hGTu9/2o6Fftgm8aSYe757BvBbiLOlF0DRhqfmOOuwUqDc9iVPEcu20CgYEA1O5J UqMW+Mp4Ne76JAW8h6Q5/gcW63qRYfC2bRIDlTNVfGmw8FbLTU/wU6cZe5GkI6Nr KokdKeCVd7zA/GGd5wAGl9T8RA6CZJ8AC2UUru+YYkeRcui/geWamcv9Q7PhN25j 8JmW70egvzUC2WCaTFaAqNBBlyMDu5YalJ718XMCgYBvfA8okgycGAzecjvOzeyR 2S2wzYKR5knFB1tYOix8M8anaqusiV6cGG5t3+1V0nnyeNmxrpv2Nnt41Ez8W9b5 yRwOvyuB0Qp7itfuCfLTt1xHXmO8307h0QhnY0XbiLe8YgfEQSPEFf5UuVXg4QpA Fzp/zFjhHHU08C9AlXN/4QKBgDHvI6DOgE+d46z6Ow0Bj2Hb4IGzFevpFXj7YzyW 0eJGZJDFlGn4YLrjuT9U24P/9pco9rPF7eHpOgQXbsaA+e+3MNSgbPxkzq1cID2L 2drgc0Lw96oT7P1AZA4XKXCcGX/PUn6U9jFtAcR1YRKrNeQbERcFp6wS2Qg/vkIG OTUDAoGANvD8R1sXTsp4JKSlerLPKARAFZxG8lxl+izGZh7LBr1EJHJshA6fkbFf qdYvM9L9WK8+sYxveLl5CaVvqqDdYsBYx5TQ/MAsOmuYS27WwfLYBFvAuycPtGnx uhFkBJn+pPZu8NiWCEDGq6xd3s/93jLWMTaS5PncRcMHpKpO72M= -----END RSA PRIVATE KEY----- "; /// JWT authentication. #[test] fn test_jwt() -> Result<(), Box> { let client = reqwest::blocking::Client::new(); // Expiration time resolution is 1 second, so we need to wait at least that // long to get a different JWT. let expiration = Duration::from_secs(1); let credential = Arc::new(JsonWebTokenCredential::new( jsonwebtoken::Header::new(jsonwebtoken::Algorithm::RS256), jsonwebtoken::EncodingKey::from_rsa_pem(PRIVATE_KEY)?, expiration, )); let mut authentication = BearerAuthentication::new(credential.clone()); while let Some(auth_step) = authentication.step()? { match auth_step { AuthenticationStep::Request(request) => { let auth_response = client.execute(request); authentication.respond(auth_response); } AuthenticationStep::WaitFor(duration) => { std::thread::sleep(duration); } } } let request = client .get("https://example.com") .build()? .with_authentication(&authentication)?; let auth1 = request .headers() .get(reqwest::header::AUTHORIZATION) .unwrap() .to_str()?; let mut authentication = BearerAuthentication::new(credential.clone()); while let Some(auth_step) = authentication.step()? { match auth_step { AuthenticationStep::Request(request) => { let auth_response = client.execute(request); authentication.respond(auth_response); } AuthenticationStep::WaitFor(duration) => { std::thread::sleep(duration); } } } let request = client .get("https://example.com") .build()? .with_authentication(&authentication)?; let auth2 = request .headers() .get(reqwest::header::AUTHORIZATION) .unwrap() .to_str()?; assert_eq!(auth1, auth2); // Wait for JWT to expire std::thread::sleep(expiration); let mut authentication = BearerAuthentication::new(credential.clone()); while let Some(auth_step) = authentication.step()? { match auth_step { AuthenticationStep::Request(request) => { let auth_response = client.execute(request); authentication.respond(auth_response); } AuthenticationStep::WaitFor(duration) => { std::thread::sleep(duration); } } } let request = client .get("https://example.com") .build()? .with_authentication(&authentication)?; let auth3 = request .headers() .get(reqwest::header::AUTHORIZATION) .unwrap() .to_str()?; assert_ne!(auth1, auth3); Ok(()) }