Skip to content

eclipse-biscuit/biscuit-actix-middleware

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 Unauthorized error;
  • Requests with tokens that fail parsing or cryptographic verification are rejected with a HTTP 403 Forbidden error.

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

About

No description, website, or topics provided.

Resources

License

Code of conduct

Security policy

Stars

Watchers

Forks

Packages

No packages published

Contributors 2

  •  
  •  

Languages