#jwt #axum #keycloak #oidc

axum-keycloak-auth

Protect axum routes with a JWT emitted by Keycloak

14 releases (7 breaking)

Uses new Rust 2024

new 0.8.2 Mar 25, 2025
0.8.0 Feb 20, 2025
0.6.0 Sep 12, 2024
0.5.0 Feb 2, 2024
0.1.2 Mar 16, 2023

#174 in Authentication

Download history 696/week @ 2024-12-02 506/week @ 2024-12-09 287/week @ 2024-12-16 141/week @ 2024-12-23 148/week @ 2024-12-30 302/week @ 2025-01-06 363/week @ 2025-01-13 568/week @ 2025-01-20 349/week @ 2025-01-27 422/week @ 2025-02-03 305/week @ 2025-02-10 661/week @ 2025-02-17 572/week @ 2025-02-24 563/week @ 2025-03-03 440/week @ 2025-03-10 342/week @ 2025-03-17

1,948 downloads per month
Used in leptos-keycloak-auth

MIT/Apache

94KB
1.5K SLoC

axum-keycloak-auth

Protect axum routes with a JWT emitted by Keycloak.

Features

  • Tower layer / service that can be attached to axum routers.
  • Automatic OIDC discovery
  • Forwarding only requests providing a verifiable and non-expired JWT.
  • Ability to allow forwarding a failed authentication attempt to possibly handle the authentication using another middleware.
  • Ability to access the extracted JWT data (including roles, the KC uuid, ...) in route handler function.
  • Tests to check that one or more required or forbidden Keycloak realm or client roles were included in the JWT.
  • Ability to access the JWT's raw claims in a handler, allowing to extract custom attributes.
  • An error type implementing IntoResponse providing exact information about why authentication failed in an error response.
  • Ability to define a custom role type from your application to which all roles are automatically parsed.

Planned

  • Ability to provide a custom type into which the token is parsed, with which non-standard JWT claims can be extracted without overhead.
  • Allowing fine-grained control over how an AuthError is converted into a response. Giving the user control and the ability to add context, roll their own.

Usage

This library provides KeycloakAuthLayer, a tower layer/service implementation that parses and validates a JWT.

See the Documentation for more detailed instructions!

enum Role {
    Administrator,
    Unknown(String),
}

pub fn protected_router(instance: KeycloakAuthInstance) -> Router {
    Router::new()
        .route("/protected", get(protected))
        .layer(
            KeycloakAuthLayer::<Role>::builder()
                .instance(instance)
                .passthrough_mode(PassthroughMode::Block)
                .build(),
        )
}

pub async fn protected(Extension(token): Extension<KeycloakToken<Role>>) -> Response {
    expect_role!(&token, Role::Administrator);

    info!("Token payload is {token:#?}");
    (
        StatusCode::OK,
        format!(
            "Hello {name} ({subject}). Your token is valid for another {valid_for} seconds.",
            name = token.extra.profile.preferred_username,
            subject = token.subject,
            valid_for = (token.expires_at - time::OffsetDateTime::now_utc()).whole_seconds()
        ),
    ).into_response()
}

Axum compatibility

axum-keycloak-auth axum
0.2 0.6
0.3 - 0.6 0.7
0.7 - 0.8 0.8

Development

Tests

Run test with

cargo test

Pass the --nocapture flag when developing to be able to see log/tracing output.

cargo test -- --nocapture

Dependencies

~11–27MB
~438K SLoC