pub struct TokenValidator { /* private fields */ }Expand description
JWT token validator with builder pattern
This validator collects all validation configuration upfront, then executes
the validation steps in the correct order when run() is called.
§Validation Flow
- Parse token (done before creating validator)
- Check basic integrity (header format, algorithm)
- Validate issuer (prevent SSRF)
- Verify signature (cryptographic verification)
- Validate claims (exp, nbf, iat, aud, etc.)
§Example
use jwtiny::*;
let token = ParsedToken::from_string("eyJ...")?;
let validated = TokenValidator::new(token)
.ensure_issuer(|iss| {
if iss == "https://trusted.com" {
Ok(())
} else {
Err(Error::IssuerNotTrusted(iss.to_string()))
}
})
.verify_signature(
SignatureVerification::with_secret_hs256(b"my-secret")
)
.validate_token(
ValidationConfig::default()
.require_audience("my-api")
)
.run()?;
println!("Subject: {:?}", validated.subject());Implementations§
Source§impl TokenValidator
impl TokenValidator
Sourcepub fn new(parsed: ParsedToken) -> Self
pub fn new(parsed: ParsedToken) -> Self
Create a new validator from a parsed token
Note: TokenValidator is not Clone by design. Each validator is bound
to a specific token to prevent accidental reuse with the wrong token data.
However, validation configurations (SignatureVerification, ValidationConfig)
are Clone and can be reused across multiple validators.
§Example
let token = ParsedToken::from_string("eyJ...")?;
let validator = TokenValidator::new(token);§Validating Multiple Tokens
To validate multiple tokens with the same configuration:
// Prepare reusable configuration
let signature = SignatureVerification::with_secret_hs256(b"secret");
let validation = ValidationConfig::default().require_audience("api");
let issuer_check = |iss: &str| Ok(iss == "https://trusted.com");
// Validate each token with the same config
for token_str in tokens {
let parsed = ParsedToken::from_string(&token_str)?;
let token = TokenValidator::new(parsed)
.ensure_issuer(issuer_check)
.verify_signature(signature.clone())
.validate_token(validation.clone())
.run()?;
// Use token...
}Sourcepub fn ensure_issuer<F>(self, validator: F) -> Self
pub fn ensure_issuer<F>(self, validator: F) -> Self
Ensure the issuer is trusted
Validates the iss claim before proceeding with signature verification.
Critical for preventing SSRF attacks when using JWKS fetching: an
attacker can craft a token with an arbitrary iss claim, causing your
application to fetch keys from attacker-controlled URLs.
The validator function receives the issuer string and should return:
Ok(())if the issuer is trustedErr(...)if the issuer is not trusted
§Note
The validator function must be Fn (not FnOnce) and should not mutate
captured state. This allows the validator to be used multiple times if needed.
§Example
validator.ensure_issuer(|iss| {
if iss == "https://auth.example.com" {
Ok(())
} else {
Err(Error::IssuerNotTrusted(iss.to_string()))
}
})Sourcepub fn danger_skip_issuer_validation(self) -> Self
pub fn danger_skip_issuer_validation(self) -> Self
⚠️ DANGER: Skip issuer validation (use with extreme caution!)
This bypasses issuer validation, which is a critical security check. Only use this if:
- You’re providing the signing key directly (not fetching from JWKS)
- You’re validating the issuer through other means
- You fully understand the security implications
§Security Warning
NEVER skip issuer validation when using JWKS! This enables SSRF attacks
where attackers can make your application fetch keys from arbitrary URLs.
For JWKS-based validation, you MUST use ensure_issuer().
The method name includes “danger” to make it clear this is a security-critical bypass that should only be used in specific, well-understood scenarios.
Sourcepub fn verify_signature(self, verification: SignatureVerification) -> Self
pub fn verify_signature(self, verification: SignatureVerification) -> Self
Configure signature verification
This specifies how the token signature should be verified. Options:
- Symmetric key (HMAC algorithms)
- Asymmetric public key (RSA/ECDSA algorithms)
- HTTP client for JWKS fetching (future feature)
§Example
// With symmetric key (HMAC) - algorithm-specific constructor
validator.verify_signature(
SignatureVerification::with_secret_hs256(b"my-secret")
)
// With public key (RSA) - must specify policy
validator.verify_signature(
SignatureVerification::with_key(
Key::rsa_public(der_bytes),
AlgorithmPolicy::rs256_only()
)
)
// Or use convenience constructor for RSA
validator.verify_signature(
SignatureVerification::with_rsa_rs256(der_bytes)
)Sourcepub fn validate_token(self, config: ValidationConfig) -> Self
pub fn validate_token(self, config: ValidationConfig) -> Self
Configure claims validation
This specifies how the token claims should be validated. You can:
- Validate time-based claims (exp, nbf, iat)
- Validate audience (aud)
- Set clock skew tolerance
- Add custom validation logic
§Example
validator.validate_token(
ValidationConfig::default()
.require_audience("my-api")
.max_age(3600)
.clock_skew(60)
)Sourcepub fn danger_skip_claims_validation(self) -> Self
pub fn danger_skip_claims_validation(self) -> Self
⚠️ DANGER: Skip claims validation (use with extreme caution!)
This bypasses claims validation, including critical checks like:
- Token expiration (
exp) - Not-before time (
nbf) - Audience (
aud)
§Security Warning
Skipping claims validation means you accept expired or not-yet-valid tokens. Only use this if you’re performing custom validation on the claims yourself and you fully understand the security implications.
The method name includes “danger” to make it clear this is a security-critical bypass that should only be used in specific, well-understood scenarios.
Sourcepub fn run(self) -> Result<Token>
pub fn run(self) -> Result<Token>
Run the validation pipeline
This executes all validation steps in the correct order:
- Check basic integrity (algorithm validation)
- Validate issuer (if configured)
- Verify signature (if configured)
- Validate claims (if configured)
Returns a fully validated Token that is safe to use.
§Errors
Returns an error if any validation step fails:
Error::UnsupportedAlgorithm- Invalid or unsupported algorithmError::IssuerNotTrusted- Issuer validation failedError::SignatureInvalid- Signature verification failedError::ClaimValidationFailed- Claims validation failedError::MissingKey- No key provided for signature verification
§Example
let token = validator.run()?;
println!("Token validated! Subject: {:?}", token.subject());