Skip to content
This repository has been archived by the owner on Sep 10, 2024. It is now read-only.

Commit

Permalink
Better errors on client authorization failures
Browse files Browse the repository at this point in the history
Before it would just return a 500, now it displays a proper error
message
  • Loading branch information
sandhose committed Oct 6, 2023
1 parent 9b5c8fb commit efbd7b5
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 3 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/axum-utils/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ tracing.workspace = true
url.workspace = true
ulid.workspace = true

oauth2-types = { path = "../oauth2-types" }
mas-data-model = { path = "../data-model" }
mas-http = { path = "../http", features = ["client"] }
mas-iana = { path = "../iana" }
Expand Down
77 changes: 74 additions & 3 deletions crates/axum-utils/src/client_authorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use axum::{
Form, FromRequest, FromRequestParts, TypedHeader,
},
response::IntoResponse,
BoxError,
BoxError, Json,
};
use headers::{authorization::Basic, Authorization};
use http::{Request, StatusCode};
Expand All @@ -32,6 +32,7 @@ use mas_iana::oauth::OAuthClientAuthenticationMethod;
use mas_jose::{jwk::PublicJsonWebKeySet, jwt::Jwt};
use mas_keystore::Encrypter;
use mas_storage::{oauth2::OAuth2ClientRepository, RepositoryAccess};
use oauth2_types::errors::{ClientError, ClientErrorCode};
use serde::{de::DeserializeOwned, Deserialize};
use serde_json::Value;
use thiserror::Error;
Expand Down Expand Up @@ -249,8 +250,78 @@ pub enum ClientAuthorizationError {

impl IntoResponse for ClientAuthorizationError {
fn into_response(self) -> axum::response::Response {
// TODO
StatusCode::INTERNAL_SERVER_ERROR.into_response()
match self {
ClientAuthorizationError::InvalidHeader => (
StatusCode::BAD_REQUEST,
Json(ClientError::new(
ClientErrorCode::InvalidRequest,
"Invalid Authorization header",
)),
),

ClientAuthorizationError::BadForm(err) => (
StatusCode::BAD_REQUEST,
Json(
ClientError::from(ClientErrorCode::InvalidRequest)
.with_description(format!("{err}")),
),
),

ClientAuthorizationError::ClientIdMismatch { form, credential } => {
let description = format!(
"client_id in form ({form:?}) does not match credential ({credential:?})"
);

(
StatusCode::BAD_REQUEST,
Json(
ClientError::from(ClientErrorCode::InvalidGrant)
.with_description(description),
),
)
}

ClientAuthorizationError::UnsupportedClientAssertion {
client_assertion_type,
} => (
StatusCode::BAD_REQUEST,
Json(
ClientError::from(ClientErrorCode::InvalidRequest).with_description(format!(
"Unsupported client_assertion_type: {client_assertion_type}",
)),
),
),

ClientAuthorizationError::MissingCredentials => (
StatusCode::BAD_REQUEST,
Json(ClientError::new(
ClientErrorCode::InvalidRequest,
"No credentials were presented",
)),
),

ClientAuthorizationError::InvalidRequest => (
StatusCode::BAD_REQUEST,
Json(ClientError::from(ClientErrorCode::InvalidRequest)),
),

ClientAuthorizationError::InvalidAssertion => (
StatusCode::BAD_REQUEST,
Json(ClientError::new(
ClientErrorCode::InvalidRequest,
"Invalid client_assertion",
)),
),

ClientAuthorizationError::Internal(e) => (
StatusCode::INTERNAL_SERVER_ERROR,
Json(
ClientError::from(ClientErrorCode::ServerError)
.with_description(format!("{e}")),
),
),
}
.into_response()
}
}

Expand Down

0 comments on commit efbd7b5

Please sign in to comment.