Skip to main content

Auth

Struct Auth 

Source
pub struct Auth;
Expand description

Constructor namespace for the authentication scheme plugins.

Auth is a zero-sized type that groups the factory functions for every scheme this crate offers. You never instantiate it; call its associated functions and pass the result to AppBuilder::install:

  • Auth::bearer — opaque Authorization: Bearer tokens verified by a closure.
  • Auth::basic — HTTP Basic username:password credentials verified by a closure.
  • Auth::jwt_hs256 — HS256-signed JWTs decoded into a claims principal.

§Examples

use churust_core::Churust;
use churust_auth::Auth;

#[derive(Clone)]
struct User;

// Each factory yields a plugin ready to `.install(..)`.
let _app = Churust::server()
    .install(Auth::bearer(|_t: String| async { Some(User) }))
    .build();

Implementations§

Source§

impl Auth

Source

pub fn bearer<P, F, Fut>(verify: F) -> Bearer<P, F>
where F: Fn(String) -> Fut + Send + Sync + 'static, Fut: Future<Output = Option<P>> + Send + 'static, P: Clone + Send + Sync + 'static,

Builds a Bearer plugin that authenticates Authorization: Bearer tokens.

verify is invoked with the raw token string (without the Bearer prefix, trimmed) and returns a future resolving to Some(principal) when the token is valid or None when it is not. The returned principal P is what handlers later read via Principal<P>.

§Parameters
  • verify — async closure Fn(String) -> impl Future<Output = Option<P>>, run once per request that carries a bearer token.
§Examples
use churust_core::{Churust, TestClient};
use churust_auth::{Auth, Principal};

#[derive(Clone)]
struct User { name: String }

let app = Churust::server()
    .install(Auth::bearer(|token: String| async move {
        (token == "letmein").then(|| User { name: "ada".into() })
    }))
    .routing(|r| {
        r.get("/me", |Principal(u): Principal<User>| async move { u.name });
    })
    .build();

let res = TestClient::new(app)
    .get("/me")
    .header("authorization", "Bearer letmein")
    .send()
    .await;
assert_eq!(res.text(), "ada");
Source

pub fn basic<P, F, Fut>(verify: F) -> Basic<P, F>
where F: Fn(String, String) -> Fut + Send + Sync + 'static, Fut: Future<Output = Option<P>> + Send + 'static, P: Clone + Send + Sync + 'static,

Builds a Basic plugin that authenticates HTTP Basic credentials.

On each request the plugin decodes the Authorization: Basic <base64> header into a username and password and calls verify. A return of Some(principal) authenticates the call; None, a malformed header, or a missing header leaves it unauthenticated. The decoded principal P is read by handlers via Principal<P>.

§Parameters
  • verify — async closure Fn(String, String) -> impl Future<Output = Option<P>> receiving (username, password).
§Gotcha

HTTP Basic transmits the password in reversibly-encoded (base64) form, so only use it over TLS.

§Examples
use churust_core::{Churust, TestClient};
use churust_auth::{Auth, Principal};

#[derive(Clone)]
struct User { name: String }

let app = Churust::server()
    .install(Auth::basic(|u: String, p: String| async move {
        (u == "admin" && p == "pw").then(|| User { name: u })
    }))
    .routing(|r| {
        r.get("/me", |Principal(u): Principal<User>| async move { u.name });
    })
    .build();

// base64("admin:pw") == "YWRtaW46cHc="
let res = TestClient::new(app)
    .get("/me")
    .header("authorization", "Basic YWRtaW46cHc=")
    .send()
    .await;
assert_eq!(res.text(), "admin");
Source§

impl Auth

Source

pub fn jwt_hs256<C>(secret: &[u8]) -> Jwt<C>
where C: DeserializeOwned + Clone + Send + Sync + 'static,

Builds a Jwt plugin that verifies HS256-signed JWT bearer tokens with an HMAC secret.

Uses the default jsonwebtoken validation for the HS256 algorithm (which, among other things, requires and checks an exp claim). Valid tokens are decoded into the claims type C and inserted as the principal for handlers to read with Principal<C>.

§Parameters
  • secret — the shared HMAC secret bytes used to sign and verify tokens. The same bytes must be used by whatever issues the tokens.
§Gotcha

Because default validation enforces exp, a claims type without an exp field (or with one in the past) will fail to validate and leave the call unauthenticated.

§Examples
use churust_core::Churust;
use churust_auth::Auth;
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Clone)]
struct Claims { sub: String, exp: usize }

let _app = Churust::server()
    .install(Auth::jwt_hs256::<Claims>(b"shared-secret"))
    .build();

Auto Trait Implementations§

§

impl Freeze for Auth

§

impl RefUnwindSafe for Auth

§

impl Send for Auth

§

impl Sync for Auth

§

impl Unpin for Auth

§

impl UnsafeUnpin for Auth

§

impl UnwindSafe for Auth

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more