revoke-auth 0.5.0

High-performance microservices infrastructure framework built with pure Rust
Documentation
use axum::{extract::FromRequestParts, http::request::Parts};
use axum_extra::{
    TypedHeader,
    headers::{Authorization, authorization::Bearer},
};

use crate::{claims::JwtClaims, jwks::JwksStore, validator::validate_token};

#[derive(Clone)]
pub struct AuthConfig {
    pub issuer: String,
    pub audience: Option<String>,
}

#[derive(Clone)]
pub struct Auth<T: JwtClaims>(pub T);

impl<S, T> FromRequestParts<S> for Auth<T>
where
    S: Send + Sync + AsRef<JwksStore> + AsRef<AuthConfig>,
    T: JwtClaims,
{
    type Rejection = axum::http::StatusCode;

    fn from_request_parts(
        parts: &mut Parts,
        state: &S,
    ) -> impl std::future::Future<Output = Result<Self, Self::Rejection>> + Send {
        async move {
            let TypedHeader(Authorization(bearer)) =
                TypedHeader::<Authorization<Bearer>>::from_request_parts(parts, state)
                    .await
                    .map_err(|_| axum::http::StatusCode::UNAUTHORIZED)?;

            let jwks_store: &JwksStore = state.as_ref();
            let auth_config: &AuthConfig = state.as_ref();

            let claims = validate_token::<T>(
                bearer.token(),
                jwks_store,
                &auth_config.issuer,
                auth_config.audience.as_deref(),
            )
            .await
            .map_err(|_| axum::http::StatusCode::UNAUTHORIZED)?;

            Ok(Auth(claims))
        }
    }
}