1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
//! High-level [http auth](https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication) extractors for [axum](https://github.com/tokio-rs/axum)
//!
//! 🚨 This crate provides an alternative to `TypedHeader<Authorization<..>>` which you should probably [use](https://docs.rs/axum/latest/axum/struct.TypedHeader.html) instead. Take a look at the fantastic [axum-login](https://github.com/maxcountryman/axum-login) crate if your looking for more robust session management. I will continue to maintain this crate.
//!
//! # Usage
//!
//! Take a look at the following structures:
//!
//! - **Basic auth: [AuthBasic]**
//! - **Bearer auth: [AuthBearer]**
//!
//! If you need to implement custom errors (i.e., status codes and messages), use these:
//!
//! - Custom basic auth: [AuthBasicCustom]
//! - Custom bearer auth: [AuthBearerCustom]
//!
//! That's all there is to it! Check out the [repository](https://github.com/owez/axum-auth) for contributing or some more documentation.
#[cfg(not(any(feature = "auth-basic", feature = "auth-bearer")))]
compile_error!(r#"At least one feature must be enabled!"#);
#[cfg(feature = "auth-basic")]
mod auth_basic;
#[cfg(feature = "auth-bearer")]
mod auth_bearer;
#[cfg(feature = "auth-basic")]
pub use auth_basic::{AuthBasic, AuthBasicCustom};
#[cfg(feature = "auth-bearer")]
pub use auth_bearer::{AuthBearer, AuthBearerCustom};
use http::{header::AUTHORIZATION, request::Parts, StatusCode};
/// Rejection error used in the [AuthBasicCustom] and [AuthBearerCustom] extractors
pub type Rejection = (StatusCode, &'static str);
/// Default error status code used for the basic extractors
pub(crate) const ERR_DEFAULT: StatusCode = StatusCode::BAD_REQUEST;
/// The header is completely missing
pub(crate) const ERR_MISSING: &str = "`Authorization` header is missing";
/// The header has some invalid characters in it
pub(crate) const ERR_CHARS: &str = "`Authorization` header contains invalid characters";
/// The header couldn't be decoded properly for basic auth, might not have had a colon in the header
pub(crate) const ERR_DECODE: &str = "`Authorization` header could not be decoded";
/// The header was set as bearer authentication when we're expecting basic
pub(crate) const ERR_WRONG_BASIC: &str = "`Authorization` header must be for basic authentication";
/// The header was set as basic authentication when we're expecting bearer
pub(crate) const ERR_WRONG_BEARER: &str = "`Authorization` header must be a bearer token";
/// Helper trait for decoding [Parts] to a final extractor; this is the main interface into the decoding system
pub(crate) trait DecodeRequestParts: Sized {
/// Decodes all provided [Parts] into a new instance of self, going through the entire decoding cycle
///
/// To add custom errors here internally, set the `err_code` as something different
fn decode_request_parts(req: &mut Parts, err_code: StatusCode) -> Result<Self, Rejection>;
}
/// Gets the auth header from [Parts] of the request or errors with [ERR_CHARS] or [ERR_MISSING] if wrong
pub(crate) fn get_header(parts: &mut Parts, err_code: StatusCode) -> Result<&str, Rejection> {
parts
.headers
.get(AUTHORIZATION)
.ok_or((err_code, ERR_MISSING))?
.to_str()
.map_err(|_| (err_code, ERR_CHARS))
}