This is supported on crate feature auth only.
Expand description

Authorize requests using the Authorization header.

Example

use tower_http::auth::RequireAuthorizationLayer;
use hyper::{Request, Response, Body, Error};
use http::{StatusCode, header::AUTHORIZATION};
use tower::{Service, ServiceExt, ServiceBuilder, service_fn};

async fn handle(request: Request<Body>) -> Result<Response<Body>, Error> {
    Ok(Response::new(Body::empty()))
}

let mut service = ServiceBuilder::new()
    // Require the `Authorization` header to be `Bearer passwordlol`
    .layer(RequireAuthorizationLayer::bearer("passwordlol"))
    .service_fn(handle);

// Requests with the correct token are allowed through
let request = Request::builder()
    .header(AUTHORIZATION, "Bearer passwordlol")
    .body(Body::empty())
    .unwrap();

let response = service
    .ready()
    .await?
    .call(request)
    .await?;

assert_eq!(StatusCode::OK, response.status());

// Requests with an invalid token get a `401 Unauthorized` response
let request = Request::builder()
    .body(Body::empty())
    .unwrap();

let response = service
    .ready()
    .await?
    .call(request)
    .await?;

assert_eq!(StatusCode::UNAUTHORIZED, response.status());

Custom authorization schemes can be made by implementing AuthorizeRequest:

use tower_http::auth::{RequireAuthorizationLayer, AuthorizeRequest};
use hyper::{Request, Response, Body, Error};
use http::{StatusCode, header::AUTHORIZATION};
use tower::{Service, ServiceExt, ServiceBuilder, service_fn};

#[derive(Clone, Copy)]
struct MyAuth;

impl AuthorizeRequest for MyAuth {
    type Output = UserId;
    type ResponseBody = Body;

    fn authorize<B>(&mut self, request: &Request<B>) -> Option<UserId> {
        // ...
    }

    fn on_authorized<B>(&mut self, request: &mut Request<B>, user_id: UserId) {
        // Set `user_id` as a request extension so it can be accessed by other
        // services down the stack.
        request.extensions_mut().insert(user_id);
    }

    fn unauthorized_response<B>(&mut self, request: &Request<B>) -> Response<Body> {
        Response::builder()
            .status(StatusCode::UNAUTHORIZED)
            .body(Body::empty())
            .unwrap()
    }
}

#[derive(Debug)]
struct UserId(String);

async fn handle(request: Request<Body>) -> Result<Response<Body>, Error> {
    // Access the `UserId` that was set in `on_authorized`. If `handle` gets called the
    // request was authorized and `UserId` will be present.
    let user_id = request
        .extensions()
        .get::<UserId>()
        .expect("UserId will be there if request was authorized");

    println!("request from {:?}", user_id);

    Ok(Response::new(Body::empty()))
}

let service = ServiceBuilder::new()
    // Authorize requests using `MyAuth`
    .layer(RequireAuthorizationLayer::custom(MyAuth))
    .service_fn(handle);

Structs

Type that performs basic authorization.

Type that performs “bearer token” authorization.

Middleware that authorizes all requests using the Authorization header.

Layer that applies RequireAuthorization which authorizes all requests using the Authorization header.

Traits

Trait for authorizing requests.