axum_security_oidc/
error.rs1use std::fmt;
2
3#[derive(Debug)]
9#[non_exhaustive]
10pub enum VerifyError {
11 MalformedToken,
14 AlgorithmNotAllowed,
17 UnknownKey,
20 InvalidKey,
22 SignatureInvalid,
24 IssuerMismatch,
26 AudienceMismatch,
28 AuthorizedPartyMismatch,
33 AuthorizedPartyMissing,
37 Expired,
39 ImmatureToken,
41 NonceMismatch,
43 JwksUnavailable,
47 InvalidToken,
49}
50
51impl fmt::Display for VerifyError {
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 match self {
54 VerifyError::MalformedToken => f.write_str("malformed ID token"),
55 VerifyError::AlgorithmNotAllowed => {
56 f.write_str("ID token signing algorithm is not allowed")
57 }
58 VerifyError::UnknownKey => f.write_str("no JWKS key matches the ID token"),
59 VerifyError::InvalidKey => f.write_str("JWKS key could not be used for verification"),
60 VerifyError::SignatureInvalid => f.write_str("ID token signature is invalid"),
61 VerifyError::IssuerMismatch => f.write_str("ID token issuer does not match"),
62 VerifyError::AudienceMismatch => f.write_str("ID token audience does not match"),
63 VerifyError::AuthorizedPartyMismatch => {
64 f.write_str("ID token authorized party (azp) does not match")
65 }
66 VerifyError::AuthorizedPartyMissing => {
67 f.write_str("ID token has multiple audiences but no authorized party (azp)")
68 }
69 VerifyError::Expired => f.write_str("ID token has expired"),
70 VerifyError::ImmatureToken => f.write_str("ID token is not yet valid"),
71 VerifyError::NonceMismatch => f.write_str("ID token nonce does not match"),
72 VerifyError::JwksUnavailable => f.write_str("could not fetch the provider's JWKS"),
73 VerifyError::InvalidToken => f.write_str("ID token failed verification"),
74 }
75 }
76}
77
78impl std::error::Error for VerifyError {}
79
80#[derive(Debug)]
83#[non_exhaustive]
84pub enum DiscoveryError {
85 InvalidIssuerUrl(url::ParseError),
87 Http(axum_security_oauth2::HttpError),
89 Status(u16),
91 Parse(serde_json::Error),
93 IssuerMismatch,
96}
97
98impl std::fmt::Display for DiscoveryError {
99 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100 match self {
101 DiscoveryError::InvalidIssuerUrl(e) => write!(f, "invalid issuer URL: {e}"),
102 DiscoveryError::Http(e) => write!(f, "discovery request failed: {e}"),
103 DiscoveryError::Status(status) => {
104 write!(f, "discovery endpoint returned status {status}")
105 }
106 DiscoveryError::Parse(e) => write!(f, "could not parse provider metadata: {e}"),
107 DiscoveryError::IssuerMismatch => {
108 f.write_str("provider metadata issuer does not match the requested issuer")
109 }
110 }
111 }
112}
113
114impl std::error::Error for DiscoveryError {
115 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
116 match self {
117 DiscoveryError::InvalidIssuerUrl(e) => Some(e),
118 DiscoveryError::Http(e) => Some(e),
119 DiscoveryError::Parse(e) => Some(e),
120 DiscoveryError::Status(_) | DiscoveryError::IssuerMismatch => None,
121 }
122 }
123}
124
125#[derive(Debug)]
128#[non_exhaustive]
129pub enum OidcError {
130 Exchange(axum_security_oauth2::Error),
132 NoIdToken,
135 Verify(VerifyError),
137}
138
139impl fmt::Display for OidcError {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 match self {
142 OidcError::Exchange(e) => write!(f, "authorization code exchange failed: {e}"),
143 OidcError::NoIdToken => f.write_str("token response contained no id_token"),
144 OidcError::Verify(e) => write!(f, "ID token verification failed: {e}"),
145 }
146 }
147}
148
149impl std::error::Error for OidcError {
150 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
151 match self {
152 OidcError::Exchange(e) => Some(e),
153 OidcError::Verify(e) => Some(e),
154 OidcError::NoIdToken => None,
155 }
156 }
157}
158
159#[derive(Debug)]
166pub enum ClaimsError {
167 Deserialize(serde_json::Error),
169}
170
171impl fmt::Display for ClaimsError {
172 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
173 match self {
174 ClaimsError::Deserialize(e) => write!(f, "could not deserialize ID token claims: {e}"),
175 }
176 }
177}
178
179impl std::error::Error for ClaimsError {
180 fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
181 match self {
182 ClaimsError::Deserialize(e) => Some(e),
183 }
184 }
185}