mirror of
https://github.com/TECHNOFAB11/jwt-authorizer.git
synced 2025-12-11 23:50:07 +01:00
fix: validation algs
- fix: missing alg in jwk panics - fix: add valid algs if alg missing (alg in jwk is optional, RFC7517#section-4.4)
This commit is contained in:
parent
d740102908
commit
5f148d3631
2 changed files with 54 additions and 12 deletions
|
|
@ -64,7 +64,14 @@ where
|
||||||
Authorizer {
|
Authorizer {
|
||||||
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
||||||
kid: None,
|
kid: None,
|
||||||
alg: vec![Algorithm::RS256, Algorithm::RS384, Algorithm::RS512],
|
algs: vec![
|
||||||
|
Algorithm::RS256,
|
||||||
|
Algorithm::RS384,
|
||||||
|
Algorithm::RS512,
|
||||||
|
Algorithm::PS256,
|
||||||
|
Algorithm::PS384,
|
||||||
|
Algorithm::PS512,
|
||||||
|
],
|
||||||
key,
|
key,
|
||||||
})),
|
})),
|
||||||
claims_checker,
|
claims_checker,
|
||||||
|
|
@ -77,7 +84,14 @@ where
|
||||||
Authorizer {
|
Authorizer {
|
||||||
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
||||||
kid: None,
|
kid: None,
|
||||||
alg: vec![Algorithm::RS256, Algorithm::RS384, Algorithm::RS512],
|
algs: vec![
|
||||||
|
Algorithm::RS256,
|
||||||
|
Algorithm::RS384,
|
||||||
|
Algorithm::RS512,
|
||||||
|
Algorithm::PS256,
|
||||||
|
Algorithm::PS384,
|
||||||
|
Algorithm::PS512,
|
||||||
|
],
|
||||||
key,
|
key,
|
||||||
})),
|
})),
|
||||||
claims_checker,
|
claims_checker,
|
||||||
|
|
@ -90,7 +104,7 @@ where
|
||||||
Authorizer {
|
Authorizer {
|
||||||
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
||||||
kid: None,
|
kid: None,
|
||||||
alg: vec![Algorithm::ES256, Algorithm::ES384],
|
algs: vec![Algorithm::ES256, Algorithm::ES384],
|
||||||
key,
|
key,
|
||||||
})),
|
})),
|
||||||
claims_checker,
|
claims_checker,
|
||||||
|
|
@ -103,7 +117,7 @@ where
|
||||||
Authorizer {
|
Authorizer {
|
||||||
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
||||||
kid: None,
|
kid: None,
|
||||||
alg: vec![Algorithm::ES256, Algorithm::ES384],
|
algs: vec![Algorithm::ES256, Algorithm::ES384],
|
||||||
key,
|
key,
|
||||||
})),
|
})),
|
||||||
claims_checker,
|
claims_checker,
|
||||||
|
|
@ -116,7 +130,7 @@ where
|
||||||
Authorizer {
|
Authorizer {
|
||||||
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
||||||
kid: None,
|
kid: None,
|
||||||
alg: vec![Algorithm::EdDSA],
|
algs: vec![Algorithm::EdDSA],
|
||||||
key,
|
key,
|
||||||
})),
|
})),
|
||||||
claims_checker,
|
claims_checker,
|
||||||
|
|
@ -129,7 +143,7 @@ where
|
||||||
Authorizer {
|
Authorizer {
|
||||||
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
||||||
kid: None,
|
kid: None,
|
||||||
alg: vec![Algorithm::EdDSA],
|
algs: vec![Algorithm::EdDSA],
|
||||||
key,
|
key,
|
||||||
})),
|
})),
|
||||||
claims_checker,
|
claims_checker,
|
||||||
|
|
@ -142,7 +156,7 @@ where
|
||||||
Authorizer {
|
Authorizer {
|
||||||
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
key_source: KeySource::SingleKeySource(Arc::new(KeyData {
|
||||||
kid: None,
|
kid: None,
|
||||||
alg: vec![Algorithm::HS256, Algorithm::HS384, Algorithm::HS512],
|
algs: vec![Algorithm::HS256, Algorithm::HS384, Algorithm::HS512],
|
||||||
key,
|
key,
|
||||||
})),
|
})),
|
||||||
claims_checker,
|
claims_checker,
|
||||||
|
|
@ -214,7 +228,7 @@ where
|
||||||
let header = decode_header(token)?;
|
let header = decode_header(token)?;
|
||||||
// TODO: (optimisation) build & store jwt_validation in key data, to avoid rebuilding it for each check
|
// TODO: (optimisation) build & store jwt_validation in key data, to avoid rebuilding it for each check
|
||||||
let val_key = self.key_source.get_key(header).await?;
|
let val_key = self.key_source.get_key(header).await?;
|
||||||
let jwt_validation = &self.validation.to_jwt_validation(val_key.alg.clone());
|
let jwt_validation = &self.validation.to_jwt_validation(val_key.algs.clone());
|
||||||
let token_data = decode::<C>(token, &val_key.key, jwt_validation)?;
|
let token_data = decode::<C>(token, &val_key.key, jwt_validation)?;
|
||||||
|
|
||||||
if let Some(ref checker) = self.claims_checker {
|
if let Some(ref checker) = self.claims_checker {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
use std::{str::FromStr, sync::Arc};
|
use std::{str::FromStr, sync::Arc};
|
||||||
|
|
||||||
use jsonwebtoken::{jwk::Jwk, Algorithm, DecodingKey, Header};
|
use jsonwebtoken::{
|
||||||
|
jwk::{AlgorithmParameters, Jwk},
|
||||||
|
Algorithm, DecodingKey, Header,
|
||||||
|
};
|
||||||
|
|
||||||
use crate::error::AuthError;
|
use crate::error::AuthError;
|
||||||
|
|
||||||
|
|
@ -21,15 +24,40 @@ pub enum KeySource {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct KeyData {
|
pub struct KeyData {
|
||||||
pub kid: Option<String>,
|
pub kid: Option<String>,
|
||||||
pub alg: Vec<Algorithm>,
|
/// valid algorithms
|
||||||
|
pub algs: Vec<Algorithm>,
|
||||||
pub key: DecodingKey,
|
pub key: DecodingKey,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_valid_algs(key: &Jwk) -> Vec<Algorithm> {
|
||||||
|
if let Some(key_alg) = key.common.key_algorithm {
|
||||||
|
// if alg is not correct => no valid algs => empty array
|
||||||
|
Algorithm::from_str(key_alg.to_string().as_str()).map_or(vec![], |a| vec![a])
|
||||||
|
} else {
|
||||||
|
// guessing valid algs from key structure
|
||||||
|
match key.algorithm {
|
||||||
|
AlgorithmParameters::EllipticCurve(_) => {
|
||||||
|
vec![Algorithm::ES256, Algorithm::ES384]
|
||||||
|
}
|
||||||
|
AlgorithmParameters::RSA(_) => vec![
|
||||||
|
Algorithm::RS256,
|
||||||
|
Algorithm::RS384,
|
||||||
|
Algorithm::RS512,
|
||||||
|
Algorithm::PS256,
|
||||||
|
Algorithm::PS384,
|
||||||
|
Algorithm::PS512,
|
||||||
|
],
|
||||||
|
AlgorithmParameters::OctetKey(_) => vec![Algorithm::EdDSA],
|
||||||
|
AlgorithmParameters::OctetKeyPair(_) => vec![Algorithm::HS256, Algorithm::HS384, Algorithm::HS512],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl KeyData {
|
impl KeyData {
|
||||||
pub fn from_jwk(key: &Jwk) -> Result<KeyData, jsonwebtoken::errors::Error> {
|
pub fn from_jwk(key: &Jwk) -> Result<KeyData, jsonwebtoken::errors::Error> {
|
||||||
Ok(KeyData {
|
Ok(KeyData {
|
||||||
kid: key.common.key_id.clone(),
|
kid: key.common.key_id.clone(),
|
||||||
alg: vec![Algorithm::from_str(key.common.key_algorithm.unwrap().to_string().as_str())?],
|
algs: get_valid_algs(key),
|
||||||
key: DecodingKey::from_jwk(key)?,
|
key: DecodingKey::from_jwk(key)?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -55,7 +83,7 @@ impl KeySet {
|
||||||
|
|
||||||
/// Find the key in the set that matches the given key id, if any.
|
/// Find the key in the set that matches the given key id, if any.
|
||||||
pub fn find_alg(&self, alg: &Algorithm) -> Option<&Arc<KeyData>> {
|
pub fn find_alg(&self, alg: &Algorithm) -> Option<&Arc<KeyData>> {
|
||||||
self.0.iter().find(|k| k.alg.contains(alg))
|
self.0.iter().find(|k| k.algs.contains(alg))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Find first key.
|
/// Find first key.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue