mirror of
https://github.com/tokio-rs/axum.git
synced 2024-11-25 08:37:29 +01:00
Use tower http auth layer in kv store example (#171)
This commit is contained in:
parent
a790abca87
commit
387de8b426
1 changed files with 5 additions and 35 deletions
|
@ -7,8 +7,7 @@
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use axum::{
|
use axum::{
|
||||||
async_trait,
|
extract::{ContentLengthLimit, Extension, Path},
|
||||||
extract::{extractor_middleware, ContentLengthLimit, Extension, Path, RequestParts},
|
|
||||||
prelude::*,
|
prelude::*,
|
||||||
response::IntoResponse,
|
response::IntoResponse,
|
||||||
routing::BoxRoute,
|
routing::BoxRoute,
|
||||||
|
@ -25,7 +24,8 @@ use std::{
|
||||||
};
|
};
|
||||||
use tower::{BoxError, ServiceBuilder};
|
use tower::{BoxError, ServiceBuilder};
|
||||||
use tower_http::{
|
use tower_http::{
|
||||||
add_extension::AddExtensionLayer, compression::CompressionLayer, trace::TraceLayer,
|
add_extension::AddExtensionLayer, auth::RequireAuthorizationLayer,
|
||||||
|
compression::CompressionLayer, trace::TraceLayer,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
|
@ -118,41 +118,11 @@ fn admin_routes() -> BoxRoute<hyper::Body> {
|
||||||
|
|
||||||
route("/keys", delete(delete_all_keys))
|
route("/keys", delete(delete_all_keys))
|
||||||
.route("/key/:key", delete(remove_key))
|
.route("/key/:key", delete(remove_key))
|
||||||
// Require beare auth for all admin routes
|
// Require bearer auth for all admin routes
|
||||||
.layer(extractor_middleware::<RequireAuth>())
|
.layer(RequireAuthorizationLayer::bearer("secret-token"))
|
||||||
.boxed()
|
.boxed()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An extractor that performs authorization.
|
|
||||||
// TODO: when https://github.com/hyperium/http-body/pull/46 is merged we can use
|
|
||||||
// `tower_http::auth::RequireAuthorization` instead
|
|
||||||
struct RequireAuth;
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<B> extract::FromRequest<B> for RequireAuth
|
|
||||||
where
|
|
||||||
B: Send,
|
|
||||||
{
|
|
||||||
type Rejection = StatusCode;
|
|
||||||
|
|
||||||
async fn from_request(req: &mut RequestParts<B>) -> Result<Self, Self::Rejection> {
|
|
||||||
let auth_header = req
|
|
||||||
.headers()
|
|
||||||
.and_then(|headers| headers.get(http::header::AUTHORIZATION))
|
|
||||||
.and_then(|value| value.to_str().ok());
|
|
||||||
|
|
||||||
if let Some(value) = auth_header {
|
|
||||||
if let Some(token) = value.strip_prefix("Bearer ") {
|
|
||||||
if token == "secret-token" {
|
|
||||||
return Ok(Self);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Err(StatusCode::UNAUTHORIZED)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn handle_error(error: BoxError) -> Result<impl IntoResponse, Infallible> {
|
fn handle_error(error: BoxError) -> Result<impl IntoResponse, Infallible> {
|
||||||
if error.is::<tower::timeout::error::Elapsed>() {
|
if error.is::<tower::timeout::error::Elapsed>() {
|
||||||
return Ok((StatusCode::REQUEST_TIMEOUT, Cow::from("request timed out")));
|
return Ok((StatusCode::REQUEST_TIMEOUT, Cow::from("request timed out")));
|
||||||
|
|
Loading…
Reference in a new issue