pub struct BasicAuthLayer<F> { /* private fields */ }auth only.Expand description
Middleware that validates HTTP Basic Auth credentials.
Issues 401 Unauthorized with WWW-Authenticate: Basic realm="Protected"
when the header is absent or malformed. Issues 401 (without the
challenge) when credentials are present but the validator returns false.
Passwords containing : are handled correctly (only the first : splits
username from password, per RFC 7617).
§Example
use rust_web_server::app::App;
use rust_web_server::auth::BasicAuthLayer;
use rust_web_server::core::New;
let app = App::new().wrap(BasicAuthLayer::new(|user, pass| {
user == "admin" && pass == "s3cret"
}));Implementations§
Source§impl<F> BasicAuthLayer<F>
impl<F> BasicAuthLayer<F>
Sourcepub fn new(validate: F) -> BasicAuthLayer<F>
pub fn new(validate: F) -> BasicAuthLayer<F>
Create a layer with a validate(username, password) -> bool closure.
Source§impl BasicAuthLayer<Box<dyn Fn(&str, &str) -> bool + Send + Sync>>
impl BasicAuthLayer<Box<dyn Fn(&str, &str) -> bool + Send + Sync>>
Sourcepub fn from_htpasswd_file(
path: &str,
) -> Result<BasicAuthLayer<Box<dyn Fn(&str, &str) -> bool + Send + Sync>>, String>
pub fn from_htpasswd_file( path: &str, ) -> Result<BasicAuthLayer<Box<dyn Fn(&str, &str) -> bool + Send + Sync>>, String>
Create a layer that validates credentials against an htpasswd-style file, loaded once at construction time (not re-read per request).
Each non-empty, non-comment (#-prefixed) line must be
username:credential, where credential is one of:
- a plain-text password (Apache’s
htpasswd -pformat), or {SHA256}followed by the base64-encoded SHA-256 digest of the password — this is rws’s own scheme, not Apache’s.
§Not supported
Apache’s real {SHA} scheme (SHA-1), $apr1$ (iterated MD5), and
bcrypt ($2y$/$2b$) are not supported — this crate has no
third-party HTTP/crypto dependencies beyond the audited RustCrypto
hash crates it already uses, and hand-rolling SHA-1/MD5/bcrypt from
scratch is not a risk worth taking for a security check. A real
Apache-generated htpasswd file (which defaults to bcrypt or $apr1$
in modern htpasswd versions) will not verify against this —
regenerate it with htpasswd -p (plain text) or write your own
{SHA256} entries, or use BasicAuthLayer::new with your own
closure (e.g. backed by the bcrypt crate) if you need real
Apache-hash compatibility.
§Errors
Returns Err if path can’t be read.
The file is re-read when it changes (18.20.0): adding or removing a user takes effect within a second, without a restart. Several files, comma-separated, are read together (one per team, say).
Trait Implementations§
Source§impl<F> Middleware for BasicAuthLayer<F>
impl<F> Middleware for BasicAuthLayer<F>
Source§fn accepts_streamed_body(
&self,
_request: &Request,
_connection: &ConnectionInfo,
) -> bool
fn accepts_streamed_body( &self, _request: &Request, _connection: &ConnectionInfo, ) -> bool
Headers only: a streamed body passes through untouched.
fn handle( &self, request: &Request, connection: &ConnectionInfo, next: &dyn Application, ) -> Result<Response, String>
Source§fn runs_inline(&self, _request: &Request, _connection: &ConnectionInfo) -> bool
fn runs_inline(&self, _request: &Request, _connection: &ConnectionInfo) -> bool
true when this layer’s own work for request never blocks (in-memory
state, atomics, short mutexes) — see Application::runs_inline. A
WithMiddleware stack runs inline only if every layer and the inner
application agree. Default false.Source§fn is_passthrough(
&self,
_request: &Request,
_connection: &ConnectionInfo,
) -> bool
fn is_passthrough( &self, _request: &Request, _connection: &ConnectionInfo, ) -> bool
true when handle would do nothing for request but call next
(e.g. a rate limit that isn’t configured). A WithMiddleware stack
offers the inner application’s execute_async only if every layer
passes the request through. Default false.Source§fn answers_streamed_body(
&self,
_request: &Request,
_connection: &ConnectionInfo,
) -> bool
fn answers_streamed_body( &self, _request: &Request, _connection: &ConnectionInfo, ) -> bool
true when this layer answers request itself — it doesn’t call
next — and reads its body as a stream (a proxy forwarding it as it
arrives). The body is then streamed whatever the layers after it and
the application would say. Requires accepts_streamed_body. Since
18.3.0.Source§fn layer_name(&self) -> &'static str
fn layer_name(&self) -> &'static str
Application::middleware_names): by default the type’s name
without its module path or generic parameters (CacheLayer). Since
18.28.0.Auto Trait Implementations§
impl<F> Freeze for BasicAuthLayer<F>where
F: Freeze,
impl<F> RefUnwindSafe for BasicAuthLayer<F>where
F: RefUnwindSafe,
impl<F> Send for BasicAuthLayer<F>where
F: Send,
impl<F> Sync for BasicAuthLayer<F>where
F: Sync,
impl<F> Unpin for BasicAuthLayer<F>where
F: Unpin,
impl<F> UnsafeUnpin for BasicAuthLayer<F>where
F: UnsafeUnpin,
impl<F> UnwindSafe for BasicAuthLayer<F>where
F: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T> ServiceExt for T
impl<T> ServiceExt for T
Source§fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>where
Self: Sized,
fn map_response_body<F>(self, f: F) -> MapResponseBody<Self, F>where
Self: Sized,
map-response-body only.Source§fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>where
Self: Sized,
fn trace_for_http(self) -> Trace<Self, SharedClassifier<ServerErrorsAsFailures>>where
Self: Sized,
trace only.Source§fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>where
Self: Sized,
fn trace_for_grpc(self) -> Trace<Self, SharedClassifier<GrpcErrorsAsFailures>>where
Self: Sized,
trace only.