#[non_exhaustive]pub enum InvalidTokenKind {
Show 25 variants
TooLarge,
NotJwt,
MalformedHeader,
CriticalHeader,
AlgorithmNotAllowed,
TypeNotAllowed,
KeyNotFound,
KeySetUnavailable,
MalformedToken,
BadSignature,
Expired,
NotYetValid,
WrongIssuer,
WrongAudience,
MissingClaim,
MalformedClaim,
SenderConstrained,
ClientNotAllowed,
TokenTooOld,
ClaimMismatch,
StaticTokenMismatch,
NoMechanism,
OAuthTokenRequired,
StaticTokenRequired,
Other,
}Expand description
Which check refused a token — see InvalidToken::kind.
Each kind names one family of checks, and as_str gives it
a stable, low-cardinality snake_case label for metrics and alerting (for
example, KeySetUnavailable is an
authorization-server outage, not junk traffic). Every kind is a 401
invalid_token; the kind changes nothing about the response.
#[non_exhaustive]: a kind may be added in a minor release, so match with a
wildcard arm. Which kind an existing refusal carries, and each kind’s label,
are stable; the InvalidToken::detail text is not.
§Examples
use oauth_resource_server::{InvalidToken, InvalidTokenKind};
/// Whether a refusal points at the authorization server rather than at the
/// caller — worth an alert of its own.
fn is_idp_trouble(invalid: &InvalidToken) -> bool {
match invalid.kind() {
InvalidTokenKind::KeySetUnavailable => true,
InvalidTokenKind::Expired | InvalidTokenKind::BadSignature => false,
_ => false,
}
}
let outage = InvalidToken::new(InvalidTokenKind::KeySetUnavailable, "JWKS refresh failed");
assert!(is_idp_trouble(&outage));
assert_eq!(outage.kind().as_str(), "key_set_unavailable");Variants (Non-exhaustive)§
This enum is marked as non-exhaustive
TooLarge
The credential is over the 16 KiB cap; refused before it is decoded.
NotJwt
The credential is not three dot-separated segments: a mistyped static token, or an opaque (non-JWT) access token.
MalformedHeader
The JWS protected header is not a base64url JSON object this crate can
read (including an alg it does not know at all, such as none).
CriticalHeader
The header lists critical extensions (crit, RFC 7515 §4.1.11), none of
which this crate supports.
AlgorithmNotAllowed
The header’s alg is not in the configured allowlist.
TypeNotAllowed
The header’s typ is not an access-token type (or is absent or JWT
while require_at_jwt is on).
KeyNotFound
No held key matches the token’s kid and alg while the key set is
healthy: not in it even after a refetch, or unknown while the
unknown-kid refetch cooldown runs and the last refresh succeeded.
The key set could not be loaded: discovery or the JWKS fetch failed, including during the refetch cooldown when the last refresh failed or no key is held at all. An authorization-server (or network) outage, not the caller’s fault.
MalformedToken
The header checks passed but the rest does not decode: the payload is not base64url JSON (an object), or the signature is not base64url.
BadSignature
The signature does not verify with the selected key (or the key could not be used to verify it).
Expired
exp is in the past (beyond the configured leeway).
NotYetValid
nbf is in the future (beyond the configured leeway), or, with
max_token_age_secs set, iat is.
WrongIssuer
iss is not exactly the configured issuer (including an iss array).
WrongAudience
No aud entry is an accepted audience.
MissingClaim
A claim the checks need is absent: exp, iss or aud; iat with
max_token_age_secs set; a required_claims entry.
MalformedClaim
A claim the checks need is present but unreadable: an exp, iss or
aud of the wrong type, an nbf (or, with max_token_age_secs set,
an iat) that is not a NumericDate.
SenderConstrained
The token carries cnf (a DPoP or mTLS sender constraint), which this
crate cannot verify and so refuses as a bearer token.
ClientNotAllowed
allowed_client_ids is set and the token’s client (client_id, else
azp) is absent or not listed.
TokenTooOld
max_token_age_secs is set and the token was issued (iat) longer ago
than that, plus the leeway.
ClaimMismatch
A required_claims entry is present in the token with another value
(and, for an array claim, not among its elements).
StaticTokenMismatch
Only static tokens are configured (no OAuth validator) and no credential is one of them.
NoMechanism
Neither a static token nor an OAuth validator is configured.
OAuthTokenRequired
A credential was accepted, but the handler needs an OAuth access token
(the axum AuthorizedToken extractor) and got a static token.
StaticTokenRequired
A credential was accepted, but the handler needs a static token (the
axum StaticTokenMatch extractor) and got an OAuth access token.
Other
Anything else: every InvalidToken built from a String or &str,
and a decoder failure this crate cannot classify more precisely.