refactor: AuthError (2)

This commit is contained in:
cduvray 2023-01-20 22:29:26 +01:00
parent 6535408979
commit dff56bf058
2 changed files with 33 additions and 41 deletions

View file

@ -1,6 +1,6 @@
use axum::{ use axum::{
http::StatusCode, http::StatusCode,
response::{IntoResponse, Response}, body::{self, Empty}, response::{IntoResponse, Response}, body::{self, Empty, BoxBody},
}; };
use http::header; use http::header;
use jsonwebtoken::Algorithm; use jsonwebtoken::Algorithm;
@ -47,71 +47,63 @@ pub enum AuthError {
InvalidClaims(), InvalidClaims(),
} }
fn response_wwwauth(status: StatusCode, bearer: &str) -> Response<BoxBody> {
let mut res = Response::new(body::boxed(Empty::new()));
*res.status_mut() = status;
let h = if bearer.is_empty() {
format!("Bearer")
} else {
format!("Bearer {}", bearer)
};
res.headers_mut().insert(header::WWW_AUTHENTICATE, h.parse().unwrap());
res
}
fn response_500() -> Response<BoxBody> {
let mut res = Response::new(body::boxed(Empty::new()));
*res.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
res
}
/// (https://datatracker.ietf.org/doc/html/rfc6750#section-3.1) /// (https://datatracker.ietf.org/doc/html/rfc6750#section-3.1)
impl IntoResponse for AuthError { impl IntoResponse for AuthError {
fn into_response(self) -> Response { fn into_response(self) -> Response {
warn!("AuthError: {}", &self);
let resp = match self { let resp = match self {
AuthError::JwksRefreshError(err) => { AuthError::JwksRefreshError(err) => {
tracing::error!("AuthErrors::JwksRefreshError: {}", err); tracing::error!("AuthErrors::JwksRefreshError: {}", err);
let mut res = Response::new(body::boxed(Empty::new())); response_500()
*res.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
res
}, },
AuthError::InvalidKey(err) => { AuthError::InvalidKey(err) => {
tracing::error!("AuthErrors::InvalidKey: {}", err); tracing::error!("AuthErrors::InvalidKey: {}", err);
let mut res = Response::new(body::boxed(Empty::new())); response_500()
*res.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
res
}, },
AuthError::JwksSerialisationError(err) => { AuthError::JwksSerialisationError(err) => {
tracing::error!("AuthErrors::JwksSerialisationError: {}", err); tracing::error!("AuthErrors::JwksSerialisationError: {}", err);
let mut res = Response::new(body::boxed(Empty::new())); response_500()
*res.status_mut() = StatusCode::INTERNAL_SERVER_ERROR;
res
}, },
AuthError::InvalidKeyAlg(err) => { AuthError::InvalidKeyAlg(err) => {
debug!("AuthErrors::InvalidKeyAlg: {:?}", err); debug!("AuthErrors::InvalidKeyAlg: {:?}", err);
let mut res = Response::new(body::boxed(Empty::new())); response_wwwauth(StatusCode::UNAUTHORIZED, "error=\"invalid_token\", error_description=\"invalid key algorithm\"")
*res.status_mut() = StatusCode::UNAUTHORIZED;
res.headers_mut().insert(header::WWW_AUTHENTICATE, "Bearer error=\"invalid_token\", error_description=\"invalid key algorithm\"".parse().unwrap());
res
}, },
AuthError::InvalidKid(err) => { AuthError::InvalidKid(err) => {
debug!("AuthErrors::InvalidKid: {}", err); debug!("AuthErrors::InvalidKid: {}", err);
let mut res = Response::new(body::boxed(Empty::new())); response_wwwauth(StatusCode::UNAUTHORIZED, "error=\"invalid_token\", error_description=\"invalid kid\"")
*res.status_mut() = StatusCode::UNAUTHORIZED;
res.headers_mut().insert(header::WWW_AUTHENTICATE, "Bearer error=\"invalid_token\", error_description=\"invalid kid\"".parse().unwrap());
res
}, },
AuthError::InvalidToken(err) => { AuthError::InvalidToken(err) => {
debug!("AuthErrors::InvalidToken: {}", err); debug!("AuthErrors::InvalidToken: {}", err);
let mut res = Response::new(body::boxed(Empty::new())); response_wwwauth(StatusCode::UNAUTHORIZED, "error=\"invalid_token\"")
*res.status_mut() = StatusCode::UNAUTHORIZED;
res.headers_mut().insert(header::WWW_AUTHENTICATE, "Bearer error=\"invalid_token\"".parse().unwrap());
res
}, },
AuthError::MissingToken() => { AuthError::MissingToken() => {
// WWW-Authenticate: Bearer realm="example"
debug!("AuthErrors::MissingToken"); debug!("AuthErrors::MissingToken");
let mut res = Response::new(body::boxed(Empty::new())); response_wwwauth(StatusCode::UNAUTHORIZED, "")
*res.status_mut() = StatusCode::UNAUTHORIZED;
res.headers_mut().insert(header::WWW_AUTHENTICATE, "Bearer".parse().unwrap());
res
}, },
AuthError::InvalidClaims() => { AuthError::InvalidClaims() => {
// WWW-Authenticate: Bearer error="insufficient_scope"
debug!("AuthErrors::InvalidClaims"); debug!("AuthErrors::InvalidClaims");
let mut res = Response::new(body::boxed(Empty::new())); response_wwwauth(StatusCode::FORBIDDEN, "error=\"insufficient_scope\"")
*res.status_mut() = StatusCode::UNAUTHORIZED;
res.headers_mut().insert(header::WWW_AUTHENTICATE, "Bearer error=\"insufficient_scope\"".parse().unwrap());
res
}, },
}; };
// let body = axum::Json(serde_json::json!({
// "error": error_message,
// }));
resp resp
} }

View file

@ -95,7 +95,7 @@ mod tests {
JWT_RSA_OK JWT_RSA_OK
).await; ).await;
assert_eq!(rsp_ko.status(), StatusCode::UNAUTHORIZED); assert_eq!(rsp_ko.status(), StatusCode::FORBIDDEN);
let h = rsp_ko.headers().get(http::header::WWW_AUTHENTICATE); let h = rsp_ko.headers().get(http::header::WWW_AUTHENTICATE);
assert!(h.is_some(), "WWW-AUTHENTICATE header missing!"); assert!(h.is_some(), "WWW-AUTHENTICATE header missing!");