diff --git a/CHANGELOG.md b/CHANGELOG.md index d3a37e4..6076e67 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 6.0.0 (unreleased) + +- Update Ring to 0.14 +- Remove `iat` check to match the JWT spec + ## 5.0.1 (2018-09-10) - Add implementation of FromStr for Algorithm diff --git a/Cargo.toml b/Cargo.toml index 6ec7278..3a4ab59 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "jsonwebtoken" -version = "5.0.1" +version = "6.0.0" authors = ["Vincent Prouillet "] license = "MIT" readme = "README.md" diff --git a/README.md b/README.md index 4ba0f6b..8cc8f89 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Add the following to Cargo.toml: ```toml -jsonwebtoken = "5" +jsonwebtoken = "6" serde_derive = "1" serde = "1" ``` @@ -72,7 +72,7 @@ let header = decode_header(&token)?; This does not perform any validation on the token. #### Validation -This library validates automatically the `iat`, `exp` and `nbf` claims if present. You can also validate the `sub`, `iss` and `aud` but +This library validates automatically the `exp` and `nbf` claims if present. You can also validate the `sub`, `iss` and `aud` but those require setting the expected value in the `Validation` struct. Since validating time fields is always a bit tricky due to clock skew, @@ -87,7 +87,7 @@ use jsonwebtoken::{Validation, Algorithm}; let validation = Validation::default(); // Quick way to setup a validation where only the algorithm changes let validation = Validation::new(Algorithm::HS512); -// Adding some leeway (in seconds) for iat, exp and nbf checks +// Adding some leeway (in seconds) for exp and nbf checks let mut validation = Validation {leeway: 60, ..Default::default()}; // Checking issuer let mut validation = Validation {iss: Some("issuer".to_string()), ..Default::default()}; diff --git a/src/errors.rs b/src/errors.rs index 5147548..8111596 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -52,8 +52,6 @@ pub enum ErrorKind { InvalidAudience, /// When a token’s `aud` claim does not match one of the expected audience values InvalidSubject, - /// When a token’s `iat` claim is in the future - InvalidIssuedAt, /// When a token’s nbf claim represents a time in the future ImmatureSignature, /// When the algorithm in the header doesn't match the one passed to `decode` @@ -89,7 +87,6 @@ impl StdError for Error { ErrorKind::InvalidIssuer => "invalid issuer", ErrorKind::InvalidAudience => "invalid audience", ErrorKind::InvalidSubject => "invalid subject", - ErrorKind::InvalidIssuedAt => "invalid issued at", ErrorKind::ImmatureSignature => "immature signature", ErrorKind::InvalidAlgorithm => "algorithms don't match", ErrorKind::Base64(ref err) => err.description(), @@ -110,7 +107,6 @@ impl StdError for Error { ErrorKind::InvalidIssuer => None, ErrorKind::InvalidAudience => None, ErrorKind::InvalidSubject => None, - ErrorKind::InvalidIssuedAt => None, ErrorKind::ImmatureSignature => None, ErrorKind::InvalidAlgorithm => None, ErrorKind::Base64(ref err) => Some(err), @@ -133,7 +129,6 @@ impl fmt::Display for Error { ErrorKind::InvalidIssuer => write!(f, "invalid issuer"), ErrorKind::InvalidAudience => write!(f, "invalid audience"), ErrorKind::InvalidSubject => write!(f, "invalid subject"), - ErrorKind::InvalidIssuedAt => write!(f, "invalid issued at"), ErrorKind::ImmatureSignature => write!(f, "immature signature"), ErrorKind::InvalidAlgorithm => write!(f, "algorithms don't match"), ErrorKind::Base64(ref err) => write!(f, "base64 error: {}", err), diff --git a/src/validation.rs b/src/validation.rs index 3684823..293147a 100644 --- a/src/validation.rs +++ b/src/validation.rs @@ -37,17 +37,11 @@ pub struct Validation { /// /// Defaults to `true`. pub validate_exp: bool, - /// Whether to validate the `iat` field. - /// - /// It will return an error if the time in the `iat` field is in the future. - /// - /// Defaults to `true`. - pub validate_iat: bool, /// Whether to validate the `nbf` field. /// /// It will return an error if the current timestamp is before the time in the `nbf` field. /// - /// Defaults to `true`. + /// Defaults to `false`. pub validate_nbf: bool, /// If it contains a value, the validation will check that the `aud` field is the same as the /// one provided and will error otherwise. @@ -94,7 +88,6 @@ impl Default for Validation { leeway: 0, validate_exp: true, - validate_iat: false, validate_nbf: false, iss: None, @@ -109,16 +102,6 @@ impl Default for Validation { pub fn validate(claims: &Map, options: &Validation) -> Result<()> { let now = Utc::now().timestamp(); - if options.validate_iat { - if let Some(iat) = claims.get("iat") { - if from_value::(iat.clone())? > now + options.leeway { - return Err(new_error(ErrorKind::InvalidIssuedAt)); - } - } else { - return Err(new_error(ErrorKind::InvalidIssuedAt)); - } - } - if options.validate_exp { if let Some(exp) = claims.get("exp") { if from_value::(exp.clone())? < now - options.leeway { @@ -182,45 +165,6 @@ mod tests { use errors::ErrorKind; - #[test] - fn iat_in_past_ok() { - let mut claims = Map::new(); - claims.insert("iat".to_string(), to_value(Utc::now().timestamp() - 10000).unwrap()); - let validation = - Validation { validate_exp: false, validate_iat: true, ..Validation::default() }; - let res = validate(&claims, &validation); - assert!(res.is_ok()); - } - - #[test] - fn iat_in_future_fails() { - let mut claims = Map::new(); - claims.insert("iat".to_string(), to_value(Utc::now().timestamp() + 100000).unwrap()); - let validation = - Validation { validate_exp: false, validate_iat: true, ..Validation::default() }; - let res = validate(&claims, &validation); - assert!(res.is_err()); - - match res.unwrap_err().kind() { - &ErrorKind::InvalidIssuedAt => (), - _ => assert!(false), - }; - } - - #[test] - fn iat_in_future_but_in_leeway_ok() { - let mut claims = Map::new(); - claims.insert("iat".to_string(), to_value(Utc::now().timestamp() + 50).unwrap()); - let validation = Validation { - leeway: 1000 * 60, - validate_iat: true, - validate_exp: false, - ..Default::default() - }; - let res = validate(&claims, &validation); - assert!(res.is_ok()); - } - #[test] fn exp_in_future_ok() { let mut claims = Map::new();