checking iss for multiple values (#173)

This commit is contained in:
Saber Haj Rabiee 2021-02-21 06:01:28 -08:00 committed by Vincent Prouillet
parent 48770d4797
commit da761fe039
2 changed files with 43 additions and 31 deletions

View File

@ -169,7 +169,7 @@ struct Validation {
pub validate_exp: bool, // Default: true
pub validate_nbf: bool, // Default: false
pub aud: Option<HashSet<String>>, // Default: None
pub iss: Option<String>, // Default: None
pub iss: Option<HashSet<String>>, // Default: None
pub sub: Option<String>, // Default: None
pub algorithms: Vec<Algorithm>, // Default: vec![Algorithm::HS256]
}
@ -185,7 +185,9 @@ let validation = Validation::new(Algorithm::HS512);
// 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()};
let mut iss = std::collections::HashSet::new();
iss.insert("issuer".to_string());
let mut validation = Validation {iss: Some(iss), ..Default::default()};
// Setting audience
let mut validation = Validation::default();
validation.set_audience(&"Me"); // string

View File

@ -49,11 +49,11 @@ pub struct Validation {
///
/// Defaults to `None`.
pub aud: Option<HashSet<String>>,
/// If it contains a value, the validation will check that the `iss` field is the same as the
/// one provided and will error otherwise.
/// If it contains a value, the validation will check that the `iss` field is a member of the
/// iss provided and will error otherwise.
///
/// Defaults to `None`.
pub iss: Option<String>,
pub iss: Option<HashSet<String>>,
/// If it contains a value, the validation will check that the `sub` field is the same as the
/// one provided and will error otherwise.
///
@ -76,6 +76,11 @@ impl Validation {
pub fn set_audience<T: ToString>(&mut self, items: &[T]) {
self.aud = Some(items.iter().map(|x| x.to_string()).collect())
}
/// `iss` is a collection of one or more acceptable iss members
pub fn set_iss<T: ToString>(&mut self, items: &[T]) {
self.iss = Some(items.iter().map(|x| x.to_string()).collect())
}
}
impl Default for Validation {
@ -124,16 +129,6 @@ pub fn validate(claims: &Map<String, Value>, options: &Validation) -> Result<()>
}
}
if let Some(ref correct_iss) = options.iss {
if let Some(iss) = claims.get("iss") {
if from_value::<String>(iss.clone())? != *correct_iss {
return Err(new_error(ErrorKind::InvalidIssuer));
}
} else {
return Err(new_error(ErrorKind::InvalidIssuer));
}
}
if let Some(ref correct_sub) = options.sub {
if let Some(sub) = claims.get("sub") {
if from_value::<String>(sub.clone())? != *correct_sub {
@ -144,6 +139,16 @@ pub fn validate(claims: &Map<String, Value>, options: &Validation) -> Result<()>
}
}
if let Some(ref correct_iss) = options.iss {
if let Some(Value::String(iss)) = claims.get("iss") {
if !correct_iss.contains(iss) {
return Err(new_error(ErrorKind::InvalidIssuer));
}
} else {
return Err(new_error(ErrorKind::InvalidIssuer));
}
}
if let Some(ref correct_aud) = options.aud {
if let Some(aud) = claims.get("aud") {
match aud {
@ -262,11 +267,11 @@ mod tests {
fn iss_ok() {
let mut claims = Map::new();
claims.insert("iss".to_string(), to_value("Keats").unwrap());
let validation = Validation {
validate_exp: false,
iss: Some("Keats".to_string()),
..Default::default()
};
let mut iss = std::collections::HashSet::new();
iss.insert("Keats".to_string());
let validation = Validation { validate_exp: false, iss: Some(iss), ..Default::default() };
let res = validate(&claims, &validation);
assert!(res.is_ok());
}
@ -275,11 +280,11 @@ mod tests {
fn iss_not_matching_fails() {
let mut claims = Map::new();
claims.insert("iss".to_string(), to_value("Hacked").unwrap());
let validation = Validation {
validate_exp: false,
iss: Some("Keats".to_string()),
..Default::default()
};
let mut iss = std::collections::HashSet::new();
iss.insert("Keats".to_string());
let validation = Validation { validate_exp: false, iss: Some(iss), ..Default::default() };
let res = validate(&claims, &validation);
assert!(res.is_err());
@ -292,11 +297,11 @@ mod tests {
#[test]
fn iss_missing_fails() {
let claims = Map::new();
let validation = Validation {
validate_exp: false,
iss: Some("Keats".to_string()),
..Default::default()
};
let mut iss = std::collections::HashSet::new();
iss.insert("Keats".to_string());
let validation = Validation { validate_exp: false, iss: Some(iss), ..Default::default() };
let res = validate(&claims, &validation);
assert!(res.is_err());
@ -420,13 +425,18 @@ mod tests {
// https://github.com/Keats/jsonwebtoken/issues/51
#[test]
#[should_panic]
fn does_validation_in_right_order() {
let mut claims = Map::new();
claims.insert("exp".to_string(), to_value(get_current_timestamp() + 10000).unwrap());
let mut iss = std::collections::HashSet::new();
iss.insert("iss no check".to_string());
let v = Validation {
leeway: 5,
validate_exp: true,
iss: Some("iss no check".to_string()),
iss: Some(iss),
sub: Some("sub no check".to_string()),
..Validation::default()
};