#jwt #jwks #axum #key-set #jwk #authorization-header #claim

axum-jwks

使用JSON Web Key Set (JWKS)在Axum中验证JWT

7个版本 (破坏性)

0.8.0 2024年8月16日
0.7.0 2024年3月14日
0.6.2 2024年1月29日
0.5.0 2023年8月28日
0.2.0 2023年3月29日

身份验证 中排名第 478

Download history 24/week @ 2024-05-20 69/week @ 2024-05-27 40/week @ 2024-06-03 50/week @ 2024-06-10 27/week @ 2024-06-17 19/week @ 2024-06-24 78/week @ 2024-07-01 180/week @ 2024-07-08 19/week @ 2024-07-15 31/week @ 2024-07-22 64/week @ 2024-07-29 60/week @ 2024-08-05 127/week @ 2024-08-12

每月下载 282

MIT 许可证

21KB
281 代码行

axum-jwks

GitHub Workflow Status Crates.io docs.rs

使用JSON Web Key Set (JWKS)在Axum中验证JWT。

功能

  • 使用openid-configuration从授权服务器获取设置。
  • 直接从授权服务器拉取JWKS
  • 验证由JWKS中的任何密钥签名的JWT,并作为带有 Authorization 头的bearer令牌提供

有关更多信息,请参阅crate文档


lib.rs:

axum-jwks允许使用JSON Web Key Set (JWKS)中的任何密钥轻松验证axum应用程序中的JWT。

用法

以下是一个如何通过JWT在路由处理程序中进行身份验证的最小有效示例

use axum::{
    async_trait,
    extract::{FromRef, FromRequestParts},
    http::request::Parts,
    http::status::StatusCode,
    response::{IntoResponse, Response},
    routing::get,
    Json,
    Router,
};
use axum_jwks::{Claims, Jwks, ParseTokenClaims, TokenError};
use serde::{Deserialize, Serialize};

// The state available to all your route handlers.
#[derive(Clone)]
struct AppState {
    jwks: Jwks,
}

impl FromRef<AppState> for Jwks {
    fn from_ref(state: &AppState) -> Self {
        state.jwks.clone()
    }
}

// The specific claims you want to parse from received JWTs.
#[derive(Deserialize, Serialize)]
struct TokenClaims {
    pub sub: String
}

impl ParseTokenClaims for TokenClaims {
    type Rejection = TokenClaimsError;
}

enum TokenClaimsError {
    Missing,
    Invalid,
}

impl IntoResponse for TokenClaimsError {
    fn into_response(self) -> Response {
        // You could do something more informative here like providing a
        // response body with different error messages for missing vs.
        // invalid tokens.
        StatusCode::UNAUTHORIZED.into_response()
    }
}

impl From<TokenError> for TokenClaimsError {
    fn from(value: TokenError) -> Self {
        match value {
            TokenError::Missing => Self::Missing,
            other => Self::Invalid,
        }
    }
}

// Handler that echos back the claims it receives. If the handler receives
// these claims, it's guaranteed that they come from a JWT that is signed
// by a key from the JWKS and is valid for the specified audience.
async fn echo_claims(Claims(claims): Claims<TokenClaims>) -> Json<TokenClaims> {
    Json(claims)
}

async fn create_router() -> Router<AppState> {
    let jwks = Jwks::from_oidc_url(
        // The Authorization Server that signs the JWTs you want to consume.
        "https://my-auth-server.example.com/.well-known/openid-configuration",
        // The audience identifier for the application. This ensures that
        // JWTs are intended for this application.
        Some("https://my-api-identifier.example.com/"),
    )
        .await
        .unwrap();

    Router::new()
        .route("/echo-claims", get(echo_claims))
        .with_state(AppState { jwks })
}

依赖关系

~13–29MB
~508K SLoC