Module tower_http::auth::async_require_authorization
source · [−]Available on crate feature
auth only.Expand description
Authorize requests using the Authorization header asynchronously.
Example
use tower_http::auth::{AsyncRequireAuthorizationLayer, AsyncAuthorizeRequest};
use hyper::{Request, Response, Body, Error};
use http::{StatusCode, header::AUTHORIZATION};
use tower::{Service, ServiceExt, ServiceBuilder, service_fn};
use futures_util::future::BoxFuture;
#[derive(Clone, Copy)]
struct MyAuth;
impl<B> AsyncAuthorizeRequest<B> for MyAuth
where
B: Send + Sync + 'static,
{
type RequestBody = B;
type ResponseBody = Body;
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(Body::empty())
.unwrap();
Err(unauthorized_response)
}
})
}
}
async fn check_auth<B>(request: &Request<B>) -> Option<UserId> {
// ...
}
#[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(AsyncRequireAuthorizationLayer::new(MyAuth))
.service_fn(handle);Or using a closure:
use tower_http::auth::{AsyncRequireAuthorizationLayer, AsyncAuthorizeRequest};
use hyper::{Request, Response, Body, Error};
use http::StatusCode;
use tower::{Service, ServiceExt, ServiceBuilder};
use futures_util::future::BoxFuture;
async fn check_auth<B>(request: &Request<B>) -> Option<UserId> {
// ...
}
#[derive(Debug)]
struct UserId(String);
async fn handle(request: Request<Body>) -> Result<Response<Body>, Error> {
// ...
}
let service = ServiceBuilder::new()
.layer(AsyncRequireAuthorizationLayer::new(|request: Request<Body>| async move {
if let Some(user_id) = check_auth(&request).await {
Ok(request)
} else {
let unauthorized_response = Response::builder()
.status(StatusCode::UNAUTHORIZED)
.body(Body::empty())
.unwrap();
Err(unauthorized_response)
}
}))
.service_fn(handle);Structs
Middleware that authorizes all requests using the Authorization header.
Layer that applies AsyncRequireAuthorization which authorizes all requests using the
Authorization header.
Response future for AsyncRequireAuthorization.
Traits
Trait for authorizing requests.