f9f87cb
commit f9f87cb
1 file changed
+19 -0
Showing 1 changed file+19-0
▼crates/justapi-core/src/middleware.rs
+19-0
| @@ -417,6 +417,7 @@ pub struct JwtAuth { | ||
417 | 417 | decoding_key: jsonwebtoken::DecodingKey, |
418 | 418 | route_rules: Vec<(String, JwtRequirement)>, |
419 | 419 | default_requirement: JwtRequirement, |
420 | + warned_aud_iss: std::sync::atomic::AtomicBool, | |
420 | 421 | } |
421 | 422 | |
422 | 423 | impl std::fmt::Debug for JwtAuth { |
| @@ -435,6 +436,7 @@ impl JwtAuth { | ||
435 | 436 | decoding_key: jsonwebtoken::DecodingKey::from_secret(secret), |
436 | 437 | route_rules: Vec::new(), |
437 | 438 | default_requirement: JwtRequirement::Required, |
439 | + warned_aud_iss: std::sync::atomic::AtomicBool::new(false), | |
438 | 440 | } |
439 | 441 | } |
440 | 442 | |
| @@ -451,6 +453,7 @@ impl JwtAuth { | ||
451 | 453 | decoding_key, |
452 | 454 | route_rules: Vec::new(), |
453 | 455 | default_requirement: JwtRequirement::Required, |
456 | + warned_aud_iss: std::sync::atomic::AtomicBool::new(false), | |
454 | 457 | }) |
455 | 458 | } |
456 | 459 | |
| @@ -464,6 +467,7 @@ impl JwtAuth { | ||
464 | 467 | decoding_key, |
465 | 468 | route_rules: Vec::new(), |
466 | 469 | default_requirement: JwtRequirement::Required, |
470 | + warned_aud_iss: std::sync::atomic::AtomicBool::new(false), | |
467 | 471 | }) |
468 | 472 | } |
469 | 473 | |
| @@ -480,6 +484,7 @@ impl JwtAuth { | ||
480 | 484 | decoding_key, |
481 | 485 | route_rules: Vec::new(), |
482 | 486 | default_requirement: JwtRequirement::Required, |
487 | + warned_aud_iss: std::sync::atomic::AtomicBool::new(false), | |
483 | 488 | } |
484 | 489 | } |
485 | 490 | |
| @@ -493,6 +498,7 @@ impl JwtAuth { | ||
493 | 498 | decoding_key, |
494 | 499 | route_rules: Vec::new(), |
495 | 500 | default_requirement: JwtRequirement::Required, |
501 | + warned_aud_iss: std::sync::atomic::AtomicBool::new(false), | |
496 | 502 | } |
497 | 503 | } |
498 | 504 | |
| @@ -590,6 +596,18 @@ fn check_claims( | ||
590 | 596 | #[async_trait] |
591 | 597 | impl<B: Send + 'static> Middleware<B> for JwtAuth { |
592 | 598 | async fn handle(&self, req: Request<B>, next: Next<'_, B>) -> Result<Response<ResponseBody>> { |
599 | + // One-time warning if aud/iss validation is not configured. | |
600 | + if self.validation.aud.is_none() | |
601 | + && self.validation.iss.is_none() | |
602 | + && !self.warned_aud_iss.swap(true, std::sync::atomic::Ordering::Relaxed) | |
603 | + { | |
604 | + tracing::warn!( | |
605 | + "JwtAuth: neither `aud` nor `iss` claim is validated. \ | |
606 | + Call `.with_audience([...])` and/or `.with_issuer(...)` \ | |
607 | + to prevent token replay across different services." | |
608 | + ); | |
609 | + } | |
610 | + | |
593 | 611 | let path = req.uri().path().to_string(); |
594 | 612 | let requirement = self.requirement_for_path(&path); |
595 | 613 | |
| @@ -1103,6 +1121,7 @@ impl OAuth2Password { | ||
1103 | 1121 | decoding_key: self.decoding_key.clone(), |
1104 | 1122 | route_rules: Vec::new(), |
1105 | 1123 | default_requirement: JwtRequirement::Required, |
1124 | + warned_aud_iss: std::sync::atomic::AtomicBool::new(false), | |
1106 | 1125 | } |
1107 | 1126 | } |
1108 | 1127 | } |
1109 | 1128 | |