refactor: Introduce helper for deserialising token parts
There are multiple points in the code where a token part needs to be deserialised (i.e. first base64-decoded, then JSON-deserialised). This is extracted to a helper function in this commit.
This commit is contained in:
parent
33c122f10e
commit
b3e8f7a91f
1 changed files with 23 additions and 10 deletions
33
src/lib.rs
33
src/lib.rs
|
@ -55,11 +55,13 @@ extern crate serde_json;
|
||||||
|
|
||||||
use base64::{decode_config, URL_SAFE};
|
use base64::{decode_config, URL_SAFE};
|
||||||
use openssl::bn::BigNum;
|
use openssl::bn::BigNum;
|
||||||
|
use openssl::error::ErrorStack;
|
||||||
|
use openssl::hash::MessageDigest;
|
||||||
use openssl::pkey::{Public, PKey};
|
use openssl::pkey::{Public, PKey};
|
||||||
use openssl::rsa::Rsa;
|
use openssl::rsa::Rsa;
|
||||||
use openssl::sign::Verifier;
|
use openssl::sign::Verifier;
|
||||||
use openssl::hash::MessageDigest;
|
use serde::de::DeserializeOwned;
|
||||||
use openssl::error::ErrorStack;
|
use serde_json::Value;
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests;
|
mod tests;
|
||||||
|
@ -135,6 +137,9 @@ pub enum ValidationError {
|
||||||
/// a more specific error variant could not be constructed.
|
/// a more specific error variant could not be constructed.
|
||||||
OpenSSL(ErrorStack),
|
OpenSSL(ErrorStack),
|
||||||
|
|
||||||
|
/// JSON decoding into a provided type failed.
|
||||||
|
JSON(serde_json::Error),
|
||||||
|
|
||||||
/// One or more claim validations failed.
|
/// One or more claim validations failed.
|
||||||
// TODO: Provide reasons?
|
// TODO: Provide reasons?
|
||||||
InvalidClaims,
|
InvalidClaims,
|
||||||
|
@ -146,6 +151,10 @@ impl From<ErrorStack> for ValidationError {
|
||||||
fn from(err: ErrorStack) -> Self { ValidationError::OpenSSL(err) }
|
fn from(err: ErrorStack) -> Self { ValidationError::OpenSSL(err) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<serde_json::Error> for ValidationError {
|
||||||
|
fn from(err: serde_json::Error) -> Self { ValidationError::JSON(err) }
|
||||||
|
}
|
||||||
|
|
||||||
/// Attempt to extract the `kid`-claim out of a JWT's header claims.
|
/// Attempt to extract the `kid`-claim out of a JWT's header claims.
|
||||||
///
|
///
|
||||||
/// This function is normally used when a token provider has multiple
|
/// This function is normally used when a token provider has multiple
|
||||||
|
@ -162,19 +171,14 @@ pub fn token_kid(jwt: &JWT) -> JWTResult<Option<String>> {
|
||||||
return Err(ValidationError::MalformedJWT);
|
return Err(ValidationError::MalformedJWT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The token components are individually base64 decoded, decode
|
// Decode only the first part of the token into a specialised
|
||||||
// just the first part and deserialise it into the expected
|
// representation:
|
||||||
// representation.
|
|
||||||
let headers_json = base64::decode_config(parts[0], URL_SAFE)
|
|
||||||
.map_err(|_| ValidationError::MalformedJWT)?;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
struct KidOnly {
|
struct KidOnly {
|
||||||
kid: Option<String>,
|
kid: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let kid_only: KidOnly = serde_json::from_slice(&headers_json)
|
let kid_only: KidOnly = deserialize_part(parts[0])?;
|
||||||
.map_err(|_| ValidationError::MalformedJWT)?;
|
|
||||||
|
|
||||||
Ok(kid_only.kid)
|
Ok(kid_only.kid)
|
||||||
}
|
}
|
||||||
|
@ -212,6 +216,15 @@ fn public_key_from_jwk(jwk: &JWK) -> JWTResult<Rsa<Public>> {
|
||||||
Rsa::from_public_components(jwk_n, jwk_e).map_err(Into::into)
|
Rsa::from_public_components(jwk_n, jwk_e).map_err(Into::into)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Decode a base64-URL encoded string and deserialise the resulting
|
||||||
|
/// JSON.
|
||||||
|
fn deserialize_part<T: DeserializeOwned>(part: &str) -> JWTResult<T> {
|
||||||
|
let json = base64::decode_config(part, URL_SAFE)
|
||||||
|
.map_err(|_| ValidationError::MalformedJWT)?;
|
||||||
|
|
||||||
|
serde_json::from_slice(&json).map_err(Into::into)
|
||||||
|
}
|
||||||
|
|
||||||
/// Validate the signature on a JWT using a provided public key.
|
/// Validate the signature on a JWT using a provided public key.
|
||||||
///
|
///
|
||||||
/// A JWT is made up of three components (headers, claims, signature)
|
/// A JWT is made up of three components (headers, claims, signature)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue