diff --git a/jwt-authorizer/Cargo.toml b/jwt-authorizer/Cargo.toml index ba6421c..f4505c8 100644 --- a/jwt-authorizer/Cargo.toml +++ b/jwt-authorizer/Cargo.toml @@ -10,7 +10,7 @@ repository = "https://github.com/cduvray/jwt-authorizer" keywords = ["jwt", "axum", "authorisation", "jwks"] [dependencies] -axum = { version = "0.7" } +axum = { version = "0.8" } chrono = { version = "0.4", optional = true } futures-util = "0.3" futures-core = "0.3" @@ -30,6 +30,7 @@ tracing = "0.1" tonic = { version = "0.12", optional = true } time = { version = "0.3", optional = true } http-body-util = "0.1.1" +aide = { version = "0.14", optional = true } [dev-dependencies] hyper = { version = "1.3.1", features = ["full"] } @@ -51,6 +52,7 @@ rustls-tls-webpki-roots = ["reqwest/rustls-tls-webpki-roots"] rustls-tls-native-roots = ["reqwest/rustls-tls-native-roots"] time = ["dep:time"] chrono = ["dep:chrono"] +aide = ["dep:aide"] [[test]] name = "tonic" diff --git a/jwt-authorizer/src/lib.rs b/jwt-authorizer/src/lib.rs index 86878bc..848a13a 100644 --- a/jwt-authorizer/src/lib.rs +++ b/jwt-authorizer/src/lib.rs @@ -1,6 +1,9 @@ #![doc = include_str!("../docs/README.md")] -use axum::{async_trait, extract::FromRequestParts, http::request::Parts}; +use axum::{ + extract::{FromRequestParts, OptionalFromRequestParts}, + http::request::Parts, +}; use jsonwebtoken::TokenData; use serde::de::DeserializeOwned; @@ -24,7 +27,6 @@ pub mod validation; #[derive(Debug, Clone, Copy, Default)] pub struct JwtClaims(pub T); -#[async_trait] impl FromRequestParts for JwtClaims where T: DeserializeOwned + Send + Sync + Clone + 'static, @@ -40,3 +42,59 @@ where } } } + +impl OptionalFromRequestParts for JwtClaims +where + T: DeserializeOwned + Send + Sync + Clone + 'static, + S: Send + Sync, +{ + type Rejection = AuthError; + + // Required method + async fn from_request_parts(parts: &mut Parts, _: &S) -> Result, Self::Rejection> { + Ok(parts + .extensions + .get::>() + .map(|claims| JwtClaims(claims.claims.clone()))) + } +} + +#[cfg(feature = "aide")] +mod aide { + + use super::JwtClaims; + use aide::{ + generate::GenContext, + openapi::{HeaderStyle, Operation, Parameter, ParameterData, ParameterSchemaOrContent, SchemaObject}, + operation::add_parameters, + OperationInput, + }; + + impl OperationInput for JwtClaims { + fn operation_input(ctx: &mut GenContext, operation: &mut Operation) { + let s = ctx.schema.subschema_for::(); + add_parameters( + ctx, + operation, + [Parameter::Header { + parameter_data: ParameterData { + name: "Authorization".to_string(), + description: Some("Jwt Bearer token".to_string()), + required: true, + format: ParameterSchemaOrContent::Schema(SchemaObject { + json_schema: s, + example: None, + external_docs: None, + }), + extensions: Default::default(), + deprecated: None, + example: None, + examples: Default::default(), + explode: None, + }, + style: HeaderStyle::Simple, + }], + ); + } + } +}