@@ -39,6 +39,13 @@ pub struct Validation {
39
39
///
40
40
/// Defaults to `60`.
41
41
pub leeway : u64 ,
42
+ /// Reject a token some time (in seconds) before the `exp` to prevent
43
+ /// expiration in transit over the network.
44
+ ///
45
+ /// The value is the inverse of `leeway`, subtracting from the validation time.
46
+ ///
47
+ /// Defaults to `0`.
48
+ pub reject_tokens_expiring_in_less_than : u64 ,
42
49
/// Whether to validate the `exp` field.
43
50
///
44
51
/// It will return an error if the time in the `exp` field is past.
@@ -94,6 +101,7 @@ impl Validation {
94
101
required_spec_claims : required_claims,
95
102
algorithms : vec ! [ alg] ,
96
103
leeway : 60 ,
104
+ reject_tokens_expiring_in_less_than : 0 ,
97
105
98
106
validate_exp : true ,
99
107
validate_nbf : false ,
@@ -246,7 +254,8 @@ pub(crate) fn validate(claims: ClaimsForValidation, options: &Validation) -> Res
246
254
if options. validate_exp || options. validate_nbf {
247
255
let now = get_current_timestamp ( ) ;
248
256
249
- if matches ! ( claims. exp, TryParse :: Parsed ( exp) if options. validate_exp && exp < now - options. leeway)
257
+ if matches ! ( claims. exp, TryParse :: Parsed ( exp) if options. validate_exp
258
+ && exp - options. reject_tokens_expiring_in_less_than < now - options. leeway )
250
259
{
251
260
return Err ( new_error ( ErrorKind :: ExpiredSignature ) ) ;
252
261
}
@@ -366,6 +375,17 @@ mod tests {
366
375
assert ! ( res. is_ok( ) ) ;
367
376
}
368
377
378
+ #[ test]
379
+ #[ wasm_bindgen_test]
380
+ fn exp_in_future_but_in_rejection_period_fails ( ) {
381
+ let claims = json ! ( { "exp" : get_current_timestamp( ) + 500 } ) ;
382
+ let mut validation = Validation :: new ( Algorithm :: HS256 ) ;
383
+ validation. leeway = 0 ;
384
+ validation. reject_tokens_expiring_in_less_than = 501 ;
385
+ let res = validate ( deserialize_claims ( & claims) , & validation) ;
386
+ assert ! ( res. is_err( ) ) ;
387
+ }
388
+
369
389
#[ test]
370
390
#[ wasm_bindgen_test]
371
391
fn exp_float_in_future_ok ( ) {
@@ -374,6 +394,17 @@ mod tests {
374
394
assert ! ( res. is_ok( ) ) ;
375
395
}
376
396
397
+ #[ test]
398
+ #[ wasm_bindgen_test]
399
+ fn exp_float_in_future_but_in_rejection_period_fails ( ) {
400
+ let claims = json ! ( { "exp" : ( get_current_timestamp( ) as f64 ) + 500.123 } ) ;
401
+ let mut validation = Validation :: new ( Algorithm :: HS256 ) ;
402
+ validation. leeway = 0 ;
403
+ validation. reject_tokens_expiring_in_less_than = 501 ;
404
+ let res = validate ( deserialize_claims ( & claims) , & validation) ;
405
+ assert ! ( res. is_err( ) ) ;
406
+ }
407
+
377
408
#[ test]
378
409
#[ wasm_bindgen_test]
379
410
fn exp_in_past_fails ( ) {
0 commit comments