1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
use std::collections::HashSet;
use jsonwebtoken::Algorithm;
/// Defines the jwt validation parameters (with defaults simplifying configuration).
pub struct Validation {
/// Add some leeway (in seconds) to the `exp` and `nbf` validation to
/// account for clock skew.
///
/// Defaults to `60`.
pub leeway: u64,
/// Whether to validate the `exp` field.
///
/// Defaults to `true`.
pub validate_exp: bool,
/// Whether to validate the `nbf` field.
///
/// Defaults to `false`.
pub validate_nbf: bool,
/// If it contains a value, the validation will check that the `aud` claim value is in the values provided.
///
/// Defaults to `None`.
pub aud: Option<Vec<String>>,
/// If it contains a value, the validation will check that the `iss` claim value is in the values provided.
///
/// Defaults to `None`.
pub iss: Option<Vec<String>>,
/// Whether to validate the JWT signature. Very insecure to turn that off!
///
/// Defaults to true.
pub validate_signature: bool,
/// Accepted algorithms
///
/// If empty anly the algorithms matching key will be authorized
pub algs: Vec<Algorithm>,
}
impl Validation {
/// new Validation with default values
pub fn new() -> Self {
Default::default()
}
/// check that the `iss` claim is a member of the values provided
pub fn iss<T: ToString>(mut self, items: &[T]) -> Self {
self.iss = Some(items.iter().map(|x| x.to_string()).collect());
self
}
/// check that the `aud` claim is a member of the items provided
pub fn aud<T: ToString>(mut self, items: &[T]) -> Self {
self.aud = Some(items.iter().map(|x| x.to_string()).collect());
self
}
/// enables or disables exp validation
pub fn exp(mut self, val: bool) -> Self {
self.validate_exp = val;
self
}
/// enables or disables nbf validation
pub fn nbf(mut self, val: bool) -> Self {
self.validate_nbf = val;
self
}
/// Add some leeway (in seconds) to the `exp` and `nbf` validation to
/// account for clock skew.
pub fn leeway(mut self, value: u64) -> Self {
self.leeway = value;
self
}
/// Whether to validate the JWT cryptographic signature
/// Very insecure to turn that off, only do it if you know what you're doing.
pub fn disable_validation(mut self) -> Self {
self.validate_signature = false;
self
}
/// Authorized algorithms.
///
/// If no algs are supplied default algs for the key will be used
/// (example for a EC key, algs = [ES256, ES384]).
pub fn algs(mut self, algs: Vec<Algorithm>) -> Self {
self.algs = algs;
self
}
pub(crate) fn to_jwt_validation(&self, default_algs: &[Algorithm]) -> jsonwebtoken::Validation {
let required_claims = if self.validate_exp {
let mut claims = HashSet::with_capacity(1);
claims.insert("exp".to_owned());
claims
} else {
HashSet::with_capacity(0)
};
let aud = self.aud.clone().map(HashSet::from_iter);
let iss = self.iss.clone().map(HashSet::from_iter);
let mut jwt_validation = jsonwebtoken::Validation::default();
jwt_validation.required_spec_claims = required_claims;
jwt_validation.leeway = self.leeway;
jwt_validation.validate_exp = self.validate_exp;
jwt_validation.validate_nbf = self.validate_nbf;
jwt_validation.iss = iss;
jwt_validation.aud = aud;
jwt_validation.sub = None;
jwt_validation.algorithms = if self.algs.is_empty() {
default_algs.to_owned()
} else {
self.algs.clone()
};
if !self.validate_signature {
jwt_validation.insecure_disable_signature_validation();
}
jwt_validation
}
}
impl Default for Validation {
fn default() -> Self {
Validation {
leeway: 60,
validate_exp: true,
validate_nbf: false,
iss: None,
aud: None,
validate_signature: true,
algs: vec![],
}
}
}