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 {
# # 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() # .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();
# };