pub trait SessionCallback: Send + Sync {
    fn callback(
        &self,
        session_data: &SessionData,
        context: &Context<'_>,
        request: &mut Request<'_>
    ) -> Result<(), SessionError> { ... } fn enable_channel_binding(&self) -> bool { ... } fn prefer<'a>(&self, a: Option<&'a Mechanism>, b: &'a Mechanism) -> Ordering { ... } fn validate(
        &self,
        session_data: &SessionData,
        context: &Context<'_>,
        validate: &mut Validate<'_>
    ) -> Result<(), ValidationError> { ... } }

Provided Methods§

source

fn callback(
    &self,
    session_data: &SessionData,
    context: &Context<'_>,
    request: &mut Request<'_>
) -> Result<(), SessionError>

Answer requests by mechanism implementation for some Properties

These requests come in one of two flavours: ‘Satisfiable’ requests asking that a value for some Property is provided, and ‘Actionable’ requests that instead need a specific action to be taken, usually performing sideband authentication to a users SSO IdP.

Since it’s not possible for the compiler to know at compile time which mechanism will be in use callbacks makes use of runtime reflection. This reflection is implemented by the Request type.

Callbacks are also passed a SessionData and a Context, providing access to data from the current Session and values from the mechanism implementation. The data that can be provided via the Context is different for each mechanism and side, and may also change depending on the step the authentication is in, refer to the documentation of Context and each mechanism that is planned to be supported for further details.

The callback is used when doing either a server-side or a client-side authentication. An example for an implementation on the client-side could look like so:

fn callback(&self, session: &SessionData, context: &Context, request: &mut Request<'_>)
    -> Result<(), SessionError>
{
    // Some requests are to provide a value for the given property by calling `satisfy`.
    request
        // satisfy calls can be chained, making use of short-circuiting
        .satisfy::<AuthId>(self.interactive_get_username()?)?
        .satisfy::<Password>(b"password")?
        .satisfy::<AuthzId>("authzid")?;

    // Other requests are to do a given action:
    if let Some(url) = request.get_action::<OpenID20AuthenticateInBrowser>() {
        open_browser_and_go_to(url);
        return Ok(());
    }
    // Additional parameters can be retrieved from the provided `Context`:
    if let Some("MIT.EDU") = context.get_ref::<Realm>() {
        // Special handling
    }

    // While there exists an error `NoCallback`, returning `Ok` here is correct too.
    Ok(())
}
source

fn enable_channel_binding(&self) -> bool

source

fn prefer<'a>(&self, a: Option<&'a Mechanism>, b: &'a Mechanism) -> Ordering

Indicate Mechanism Preference

This method allows implementors to select the preferred mechanism for a client side authentication. In that situation this function is used as a fold, and called repeatedly for all offered and available mechanisms.

An implementation should return the mechanism it prefers of the two. The comparison should behave as if a.cmp(b) was called, i.e. returning Ordering::Less prefers b, while returning Ordering::Greater prefers a. If Ordering::Equal is returned the result is undefined and MUST NOT be relied upon.

If b is not acceptable and should not be used, an implementation MUST return Ordering::Greater to indicate preference for a. This requirement is true even if a is None. a is None if only one of the offered mechanism(s) is also available to the client, this is the first call to prefer, or if the previous call to prefer indicated preference for a None a. This requirement is specified so that a client can reject all compatible mechanisms by returning Ordering::Greater.

source

fn validate(
    &self,
    session_data: &SessionData,
    context: &Context<'_>,
    validate: &mut Validate<'_>
) -> Result<(), ValidationError>

Validate an authentication exchange

This callback will only be issued on the server side of an authentication exchange to validate the data passed in by the client side (e.g. authzid/username/password for PLAIN).

Returning an Err from this method should only be used to indicate a fatal unrecoverable error, and not a completed authentication exchange but failed authentication (e.g. client sent an invalid password, but followed the authentication protocol itself correctly). Returning Err will immediately abort the authentication exchange and bubble the error up to the protocol handler. It will most importantly not finish the authentication exchange and may lead to invalid data being sent to the other party.

To signal a failed authentication the Value in the Validation should be a Result type and set to the appropriate Error value by the callback instead.

Implementors§