Expand description
Shared multi-scheme authentication for RTSP and HTTP clients and servers.
Auth is not transport-specific: RTSP, TS-over-HTTP, HLS-pull, and any other
credentialed origin all face the same handful of schemes. This crate holds
one Credentials model, one client-side challenge->response
helper (respond/Authenticator), and one server-side
challenge+verify type (Verifier), so rtsp-runtime, multimux’s HTTP
input adapters, and multimux’s own shared output-auth middleware all
answer/issue WWW-Authenticate challenges through the same code instead
of re-implementing it per client or per origin.
§Client vs. server
- Client (
respond/Authenticator): given aWWW-Authenticatechallenge received from a server, compute theAuthorizationvalue to answer it. - Server (
Verifier): given a configured credential, produce theWWW-Authenticatechallenge to send on a401(Verifier::challenge), and check an incomingAuthorizationheader against it (Verifier::verify).
§Schemes
- Basic (RFC 7617) and Digest (RFC 7616) — the challenge-parse and
response computation is delegated to the mature
http_authcrate. RTSP reuses these verbatim (RFC 2326 §14/§16): only theuridiffers (the RTSP request URI, not an HTTP URL). - Bearer (RFC 6750) — no challenge round-trip is required; the
Authorizationvalue is alwaysBearer <token>. - Forwarded (server-side only,
Verifier::forwarded) — trusts a fronting reverse proxy that has already authenticated the caller and forwards the authenticated username in a configured header. NoCredentials/challenge-response round-trip. See theVerifiermodule docs for the trust assumption. - SignedUrl (server-side only,
Verifier::signed_url, issue #747) — CDN-style HMAC-SHA256 signed query-string tokens (exp/kid/sig[/ip]), so a player can fetch segments with no credential header at all. Key rotation via multiple simultaneously-validkids, optional IP scoping, constant-time signature compare. Seesigned_urlfor the wire form and canonical string.
§Usage
For a single request:
use broadcast_auth::{respond, Credentials, RequestContext};
let value = respond(
"Basic realm=\"cameras\"",
&RequestContext::new("GET", "/stream"),
Credentials::new("admin", "12345"),
)
.unwrap();
assert!(value.starts_with("Basic "));Across a session (Digest’s nc must advance on every request — keep the
Authenticator alive, don’t call respond per-request):
use broadcast_auth::{Authenticator, Credentials, RequestContext};
let mut auth = Authenticator::from_challenge(
"Digest realm=\"cameras\", nonce=\"abc123\", qop=\"auth\"",
Credentials::new("admin", "12345"),
)
.unwrap();
let first = auth
.authorization(&RequestContext::new("DESCRIBE", "rtsp://cam/stream"))
.unwrap();
let second = auth
.authorization(&RequestContext::new("PLAY", "rtsp://cam/stream"))
.unwrap();
assert_ne!(first, second, "nc must advance between requests");Bearer needs no challenge at all:
use broadcast_auth::Credentials;
let creds = Credentials::bearer("mytoken");
assert_eq!(creds, Credentials::Bearer { token: "mytoken".into() });Signed URLs (issue #747) mint and verify through the same
SignedUrlKeySet, no Authorization header involved:
use broadcast_auth::{AuthResult, RequestContext, SignedUrlKeySet, Verifier};
let keys = SignedUrlKeySet::new([("key-1".to_string(), vec![0u8; 32])]).unwrap();
let exp = 4_000_000_000; // far future
let query = keys.sign("key-1", "/stream/media.m3u8", exp, None).unwrap();
let verifier = Verifier::signed_url(keys);
let uri = format!("/stream/media.m3u8?{query}");
assert_eq!(verifier.verify(&RequestContext::new("GET", &uri)), AuthResult::Ok);Re-exports§
pub use signed_url::SignedUrlKeySet;
Modules§
- signed_
url - HMAC-signed URL access control (issue #747) — CDN-style, short-lived, tamper-proof query-string tokens that gate a media egress route without the caller carrying a credential header at all.
Structs§
- Authenticator
- Negotiates a challenge once, then answers every subsequent request in the
session (RFC 7235
WWW-Authenticate/Authorization; RFC 2326 §14 for RTSP; RFC 6750 for Bearer). - Request
Context - The request fields the Digest response hash covers (RFC 7616 §3.4.1 / RFC
2326 §14): the method, the request URI, and — for
qop=auth-int— the body. Also carries the request’s headers and transport peer address, so a server-sidecrate::Verifierscheme can see beyond theAuthorizationheader — e.g. a reverse-proxy forwarded-auth scheme readingX-Forwarded-User/X-Forwarded-For(issue #663 extensibility wave part 1). Client-side use (crate::respond/crate::Authenticator) needs neither field;Self::newdefaults both to empty/None. - Verifier
- Challenges + verifies incoming requests against one configured
Credentials(RFC 7235 origin-side auth) — see the module docs.
Enums§
- Auth
Result - The outcome of
Verifier::verify. - Credentials
- Credentials for one of the supported auth schemes.
- Error
- Errors produced by challenge parsing / response computation.
Functions§
- respond
- One-shot challenge->response: computes the
Authorizationvalue for a single request without keeping anAuthenticatoraround.
Type Aliases§
- Result
- Result alias for the crate’s fallible operations.