8 releases
| 0.3.0 | Sep 1, 2025 |
|---|---|
| 0.3.0-alpha.3 | Jul 17, 2025 |
| 0.3.0-alpha.2 | Jun 5, 2025 |
| 0.3.0-alpha.1 | Jan 16, 2025 |
| 0.1.1 | Jun 14, 2023 |
#693 in Asynchronous
25 downloads per month
33KB
285 lines
Eclipse Biscuit actix middleware
This repo is part of the eclipse biscuit project.
This middleware allows service-wide extraction and parsing of biscuit tokens.
Authorization itself still need to be handled from within endpoint handlers.
The middleware expects a base64-encoded token through the bearer token HTTP authorization scheme (an Authorization: Bearer <token> HTTP header). This token is deserialized and its cryptographic signatures verified with the provided public key.
- Requests without a bearer token are rejected with a HTTP
401 Unauthorizederror; - Requests with tokens that fail parsing or cryptographic verification are rejected with a HTTP
403 Forbiddenerror.
Token extraction logic and error handling are configurable (see Configuration example).
Working example
Here is a web server exposing GET /hello, only to tokens containing the role("admin") fact. The public key used for verifying tokens is provided through the BISCUIT_PUBLIC_KEY environment variable.
A complete, runnable example can be found in examples/readme.rs, and can be run with BISCUIT_PUBLIC_KEY=<public key> cargo run --example readme.
Optionally, you can enable tracing by running BISCUIT_PUBLIC_KEY=<public key> cargo run --example readme --features tracing to observe middleware traces as logs in the console.
use actix_web::{get, web, App, HttpResponse, HttpServer};
use biscuit_actix_middleware::BiscuitMiddleware;
use biscuit_auth::{macros::*, Biscuit, PublicKey};
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let public_key: PublicKey = std::env::var("BISCUIT_PUBLIC_KEY")
.expect("Missing BISCUIT_PUBLIC_KEY environment variable")
.parse()
.expect("Couldn't parse public key");
HttpServer::new(move || {
App::new()
.wrap(BiscuitMiddleware::new(public_key))
.service(hello)
})
.bind(("127.0.0.1", 8080))?
.run()
.await
}
#[get("/hello")]
async fn hello(biscuit: web::ReqData<Biscuit>) -> HttpResponse {
let mut authorizer = authorizer!(
r#"
allow if role("admin");
"#
).build(&biscuit).unwrap();
if authorizer.authorize().is_err() {
return HttpResponse::Forbidden().finish();
}
HttpResponse::Ok().body("Hello admin!")
}
Copyright - Licensing
Copyright 2023 Tristan Germain
Licensed under Apache License 2.0
Dependencies
~29–46MB
~694K SLoC