From dff56bf0586b01a2fcff70f23ddccedbbd258532 Mon Sep 17 00:00:00 2001 From: cduvray Date: Fri, 20 Jan 2023 22:29:26 +0100 Subject: [PATCH] refactor: AuthError (2) --- jwt-authorizer/src/error.rs | 72 +++++++++++++++++-------------------- jwt-authorizer/src/tests.rs | 2 +- 2 files changed, 33 insertions(+), 41 deletions(-) diff --git a/jwt-authorizer/src/error.rs b/jwt-authorizer/src/error.rs index bde8118..164aba8 100644 --- a/jwt-authorizer/src/error.rs +++ b/jwt-authorizer/src/error.rs @@ -1,6 +1,6 @@ use axum::{ http::StatusCode, - response::{IntoResponse, Response}, body::{self, Empty}, + response::{IntoResponse, Response}, body::{self, Empty, BoxBody}, }; use http::header; use jsonwebtoken::Algorithm; @@ -47,71 +47,63 @@ pub enum AuthError { InvalidClaims(), } +fn response_wwwauth(status: StatusCode, bearer: &str) -> Response { + 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 { + 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) impl IntoResponse for AuthError { - fn into_response(self) -> Response { - warn!("AuthError: {}", &self); + fn into_response(self) -> Response { let resp = match self { AuthError::JwksRefreshError(err) => { tracing::error!("AuthErrors::JwksRefreshError: {}", err); - let mut res = Response::new(body::boxed(Empty::new())); - *res.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - res + response_500() }, AuthError::InvalidKey(err) => { - tracing::error!("AuthErrors::InvalidKey: {}", err); - let mut res = Response::new(body::boxed(Empty::new())); - *res.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - res + tracing::error!("AuthErrors::InvalidKey: {}", err); + response_500() }, AuthError::JwksSerialisationError(err) => { - tracing::error!("AuthErrors::JwksSerialisationError: {}", err); - let mut res = Response::new(body::boxed(Empty::new())); - *res.status_mut() = StatusCode::INTERNAL_SERVER_ERROR; - res + tracing::error!("AuthErrors::JwksSerialisationError: {}", err); + response_500() }, AuthError::InvalidKeyAlg(err) => { debug!("AuthErrors::InvalidKeyAlg: {:?}", err); - let mut res = Response::new(body::boxed(Empty::new())); - *res.status_mut() = StatusCode::UNAUTHORIZED; - res.headers_mut().insert(header::WWW_AUTHENTICATE, "Bearer error=\"invalid_token\", error_description=\"invalid key algorithm\"".parse().unwrap()); - res + response_wwwauth(StatusCode::UNAUTHORIZED, "error=\"invalid_token\", error_description=\"invalid key algorithm\"") }, AuthError::InvalidKid(err) => { debug!("AuthErrors::InvalidKid: {}", err); - let mut res = Response::new(body::boxed(Empty::new())); - *res.status_mut() = StatusCode::UNAUTHORIZED; - res.headers_mut().insert(header::WWW_AUTHENTICATE, "Bearer error=\"invalid_token\", error_description=\"invalid kid\"".parse().unwrap()); - res + response_wwwauth(StatusCode::UNAUTHORIZED, "error=\"invalid_token\", error_description=\"invalid kid\"") }, AuthError::InvalidToken(err) => { debug!("AuthErrors::InvalidToken: {}", err); - let mut res = Response::new(body::boxed(Empty::new())); - *res.status_mut() = StatusCode::UNAUTHORIZED; - res.headers_mut().insert(header::WWW_AUTHENTICATE, "Bearer error=\"invalid_token\"".parse().unwrap()); - res + response_wwwauth(StatusCode::UNAUTHORIZED, "error=\"invalid_token\"") }, AuthError::MissingToken() => { - // WWW-Authenticate: Bearer realm="example" debug!("AuthErrors::MissingToken"); - let mut res = Response::new(body::boxed(Empty::new())); - *res.status_mut() = StatusCode::UNAUTHORIZED; - res.headers_mut().insert(header::WWW_AUTHENTICATE, "Bearer".parse().unwrap()); - res + response_wwwauth(StatusCode::UNAUTHORIZED, "") }, AuthError::InvalidClaims() => { - // WWW-Authenticate: Bearer error="insufficient_scope" debug!("AuthErrors::InvalidClaims"); - let mut res = Response::new(body::boxed(Empty::new())); - *res.status_mut() = StatusCode::UNAUTHORIZED; - res.headers_mut().insert(header::WWW_AUTHENTICATE, "Bearer error=\"insufficient_scope\"".parse().unwrap()); - - res + response_wwwauth(StatusCode::FORBIDDEN, "error=\"insufficient_scope\"") }, }; - // let body = axum::Json(serde_json::json!({ - // "error": error_message, - // })); resp } diff --git a/jwt-authorizer/src/tests.rs b/jwt-authorizer/src/tests.rs index 6e99b47..4322d66 100644 --- a/jwt-authorizer/src/tests.rs +++ b/jwt-authorizer/src/tests.rs @@ -95,7 +95,7 @@ mod tests { JWT_RSA_OK ).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); assert!(h.is_some(), "WWW-AUTHENTICATE header missing!");