Expand description
Authorize requests using the Authorization header asynchronously.
§Example
use tower_http::auth::{AsyncRequireAuthorizationLayer, AsyncAuthorizeRequest};
use http::{Request, Response, StatusCode, header::AUTHORIZATION};
use tower::{Service, ServiceExt, ServiceBuilder, service_fn, BoxError};
use futures_core::future::BoxFuture;
use bytes::Bytes;
use http_body_util::Full;
#[derive(Clone, Copy)]
struct MyAuth;
impl<B> AsyncAuthorizeRequest<B> for MyAuth
where
    B: Send + Sync + 'static,
{
    type RequestBody = B;
    type ResponseBody = Full<Bytes>;
    type Future = BoxFuture<'static, Result<Request<B>, Response<Self::ResponseBody>>>;
    fn authorize(&mut self, mut request: Request<B>) -> Self::Future {
        Box::pin(async {
            if let Some(user_id) = check_auth(&request).await {
                // Set `user_id` as a request extension so it can be accessed by other
                // services down the stack.
                request.extensions_mut().insert(user_id);
                Ok(request)
            } else {
                let unauthorized_response = Response::builder()
                    .status(StatusCode::UNAUTHORIZED)
                    .body(Full::<Bytes>::default())
                    .unwrap();
                Err(unauthorized_response)
            }
        })
    }
}
async fn check_auth<B>(request: &Request<B>) -> Option<UserId> {
    // ...
}
#[derive(Debug, Clone)]
struct UserId(String);
async fn handle(request: Request<Full<Bytes>>) -> Result<Response<Full<Bytes>>, BoxError> {
    // 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(Full::default()))
}
let service = ServiceBuilder::new()
    // Authorize requests using `MyAuth`
    .layer(AsyncRequireAuthorizationLayer::new(MyAuth))
    .service_fn(handle);Or using a closure:
use tower_http::auth::{AsyncRequireAuthorizationLayer, AsyncAuthorizeRequest};
use http::{Request, Response, StatusCode};
use tower::{Service, ServiceExt, ServiceBuilder, BoxError};
use futures_core::future::BoxFuture;
use http_body_util::Full;
use bytes::Bytes;
async fn check_auth<B>(request: &Request<B>) -> Option<UserId> {
    // ...
}
#[derive(Debug)]
struct UserId(String);
async fn handle(request: Request<Full<Bytes>>) -> Result<Response<Full<Bytes>>, BoxError> {
    // ...
}
let service = ServiceBuilder::new()
    .layer(AsyncRequireAuthorizationLayer::new(|request: Request<Full<Bytes>>| async move {
        if let Some(user_id) = check_auth(&request).await {
            Ok(request)
        } else {
            let unauthorized_response = Response::builder()
                .status(StatusCode::UNAUTHORIZED)
                .body(Full::<Bytes>::default())
                .unwrap();
            Err(unauthorized_response)
        }
    }))
    .service_fn(handle);Structs§
- AsyncRequire Authorization 
- Middleware that authorizes all requests using the Authorizationheader.
- AsyncRequire Authorization Layer 
- Layer that applies AsyncRequireAuthorizationwhich authorizes all requests using theAuthorizationheader.
- ResponseFuture 
- Response future for AsyncRequireAuthorization.
Traits§
- AsyncAuthorize Request 
- Trait for authorizing requests.