rusttls_jwt_authorizer/
validation.rs

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