Module tower_http::auth::require_authorization
source · [−]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<B> AuthorizeRequest<B> for MyAuth {
type ResponseBody = Body;
fn authorize(
&mut self,
request: &mut Request<B>,
) -> Result<(), Response<Self::ResponseBody>> {
if let Some(user_id) = check_auth(request) {
// 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(())
} else {
let unauthorized_response = Response::builder()
.status(StatusCode::UNAUTHORIZED)
.body(Body::empty())
.unwrap();
Err(unauthorized_response)
}
}
}
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(RequireAuthorizationLayer::custom(MyAuth))
.service_fn(handle);
Or using a closure:
use tower_http::auth::{RequireAuthorizationLayer, AuthorizeRequest};
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> {
// ...
}
let service = ServiceBuilder::new()
.layer(RequireAuthorizationLayer::custom(|request: &mut Request<Body>| {
// authorize the request
}))
.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.
Response future for RequireAuthorization
.
Traits
Trait for authorizing requests.