aliri_tower 0.2.0

Tower middleware for interacting with `aliri` authorities
Documentation

Authorizers for working with tower_http and other constructs in the ecosystem, including axum.

See the examples folder in the repository for a working example using an tonic web server. For a more ergonomic experience in axum, see the aliri_axum crate.

# use axum::extract::Path;
use axum::handler::Handler;
# use axum::routing::{get, post};
# use aliri::{jwa, jwk, jwt, Jwk, Jwks};
# use aliri_base64::Base64UrlRef;
# use aliri_clock::UnixTime;
use aliri_oauth2::{scope, policy, ScopePolicy};
use aliri_tower::Oauth2Authorizer;

# #[derive(Clone, Debug, serde::Deserialize)]
pub struct CustomClaims {
//#     iss: aliri::jwt::Issuer,
#     aud: aliri::jwt::Audiences,
#     sub: aliri::jwt::Subject,
#     scope: aliri_oauth2::oauth2::Scope,
}

impl jwt::CoreClaims for CustomClaims {
//#     fn nbf(&self) -> Option<UnixTime> { None }
#     fn exp(&self) -> Option<UnixTime> { None }
#     fn aud(&self) -> &aliri::jwt::Audiences { &self.aud }
#     fn iss(&self) -> Option<&aliri::jwt::IssuerRef> { Some(&self.iss) }
#     fn sub(&self) -> Option<&aliri::jwt::SubjectRef> { Some(&self.sub) }
}

# impl aliri_oauth2::oauth2::HasScope for CustomClaims {
#     fn scope(&self) -> &aliri_oauth2::oauth2::Scope { &self.scope }
# }
#
# fn construct_authority() -> aliri_oauth2::Authority {
#     // This authority might otherwise come from a well-known JWKS endpoint
#     let secret = Base64UrlRef::from_slice(b"test").to_owned();
#     let key = Jwk::from(jwa::Hmac::new(secret))
#         .with_algorithm(jwa::Algorithm::HS256)
#         .with_key_id(jwk::KeyId::from_static("test key"));
#
#     let mut jwks = Jwks::default();
#     jwks.add_key(key);
#
#     let validator = jwt::CoreValidator::default()
#         .ignore_expiration() // Only for demonstration purposes
#         .add_approved_algorithm(jwa::Algorithm::HS256)
#         .add_allowed_audience(jwt::Audience::from_static("my_api"))
#         .require_issuer(jwt::Issuer::from_static("authority"));
#
#     aliri_oauth2::Authority::new(jwks, validator)
# }
#
let authority = construct_authority();
let authorizer = Oauth2Authorizer::new()
.with_claims::<CustomClaims>()
.with_terse_error_handler();

let app = axum::Router::new()
.route(
"/users",
post(handle_post
.layer(authorizer.scope_layer(policy![scope!["post_user"]]))),
)
.route(
"/users/:id",
get(handle_get
.layer(authorizer.scope_layer(ScopePolicy::allow_one_from_static("get_user")))),
)
.layer(authorizer.jwt_layer(authority));
#
# async fn handle_post() {}
#
# async fn handle_get(Path(id): Path<u64>) {}
#
# async {
# axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
# };