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
//! Pluggable authentication for HTTP routes.
//!
//! Implement [`AuthProvider`] and register it via
//! [`HttpRouter::set_auth`](crate::HttpRouter::set_auth) to add authentication
//! middleware to all routes served by [`AppPlugin`](crate::AppPlugin).
//!
//! # Example
//!
//! ```no_run
//! use polaris_app::{AuthProvider, auth::AuthRejection};
//! use axum::response::IntoResponse;
//! use http::StatusCode;
//!
//! #[derive(Debug)]
//! struct BearerAuth {
//! expected_token: String,
//! }
//!
//! impl AuthProvider for BearerAuth {
//! fn authenticate(&self, parts: &http::request::Parts) -> Result<(), AuthRejection> {
//! let header = parts
//! .headers
//! .get(http::header::AUTHORIZATION)
//! .and_then(|v| v.to_str().ok());
//!
//! match header {
//! Some(val) if val == format!("Bearer {}", self.expected_token) => Ok(()),
//! _ => Err(Box::new(StatusCode::UNAUTHORIZED.into_response())),
//! }
//! }
//! }
//! ```
/// The rejection type returned by [`AuthProvider::authenticate`].
///
/// Wraps an [`axum::response::Response`] in a `Box` to keep the `Result`
/// return value small on the stack.
pub type AuthRejection = ;
/// Trait for pluggable request authentication.
///
/// Plugins implement this trait and register it via
/// [`HttpRouter::set_auth`](crate::HttpRouter::set_auth) during `build()`.
/// [`AppPlugin`](crate::AppPlugin) applies the provider as middleware in
/// `ready()`, rejecting unauthenticated requests before they reach route
/// handlers.
///
/// Authentication is intentionally synchronous — most schemes (bearer tokens,
/// API keys, HMAC signatures) only need to inspect request headers. If your
/// scheme requires async I/O (e.g., remote token introspection), perform the
/// lookup in a Tower layer registered directly via
/// [`HttpRouter::add_routes`](crate::HttpRouter::add_routes) instead.