Skip to main content

ClientCredential

Struct ClientCredential 

Source
#[non_exhaustive]
pub struct ClientCredential<'a> { pub client_secret: Option<&'a str>, pub client_assertion_type: Option<&'a str>, pub client_assertion: Option<&'a str>, pub certificate: Option<&'a ClientCertificate<'a>>, }
Expand description

How a client is authenticating on one request.

A value of its own rather than more fields on every TokenRequest variant, for the same reason RFC 8707’s resource is a separate argument: client authentication is a property of the REQUEST and is identical across every grant, so putting it on each variant would state the same thing four times, grow an enum every host copies around, and make each future grant repeat it again.

Default is a PUBLIC client: no secret, no assertion.

Debug is HAND-WRITTEN (below) and does not print the secret or the assertion. It derived one until 0.9.2, which made the guarantee on crate::http’s private Credentials – “DELIBERATELY NOT Debug … a derived Debug would put all of it verbatim into a host’s logs the first time somebody wrote tracing::debug!(?creds)” – last exactly as long as the one function call that converts the one into the other. And this is the worse of the two to leave open: it is PUBLIC API, so it is the value a host builds by hand for AuthorizationServer::token, and a host that never touches http::Credentials reaches it anyway. #[non_exhaustive]: client-assertion adds two fields and mtls adds a third, so this is four different structs depending on the flag set. Three named constructors already cover the three ways a client can authenticate (ClientCredential::secret, ClientCredential::assertion, ClientCredential::certificate), and the RFC 8705 section 4 case of binding a token for a client that authenticated some other way is a field assignment on top of one of them, which is exactly what that field’s own documentation already tells a host to do.

Fields (Non-exhaustive)§

This struct is marked as non-exhaustive
Non-exhaustive structs could have additional fields added in future. Therefore, non-exhaustive structs cannot be constructed in external crates using the traditional Struct { .. } syntax; cannot be matched against without a wildcard ..; and struct update syntax will not work.
§client_secret: Option<&'a str>

The RFC 6749 section 2.3.1 shared secret, from Authorization: Basic or from the form body. None for a public client, and None when an assertion is presented instead.

§client_assertion_type: Option<&'a str>
Available on crate feature client-assertion only.

RFC 7521 section 4.2 client_assertion_type. It MUST be crate::client_assertion::CLIENT_ASSERTION_TYPE; any other value is refused rather than ignored, because an assertion format this server does not implement is a credential it cannot check, and “cannot check” must never read as “checked out”.

§client_assertion: Option<&'a str>
Available on crate feature client-assertion only.

RFC 7523 section 2.2 client-assertion: the signed JWT itself.

§certificate: Option<&'a ClientCertificate<'a>>
Available on crate feature mtls only.

The RFC 8705 client certificate the HOST has ALREADY VERIFIED for this connection.

READ crate::mtls’s trust boundary section before setting this. This library never sees a socket, so it cannot validate a chain it did not negotiate: a host that fills this in from an unverified source (an unstripped X-Client-Cert header, a terminator that requests but does not require a certificate) has authenticated nobody, and every comparison this crate then makes is against a value the caller chose.

It does two separate jobs, either of which can apply on its own:

  • section 2, AUTHENTICATION: a client registered with crate::client::ClientAuth::Mtls is authenticated by this certificate and by nothing else. Such a client cannot authenticate through a call that leaves this None, which is the point: a host that forgets to pass the certificate gets invalid_client, never a token.
  • section 3, BINDING: the issued access token is bound to this certificate whatever the client’s authentication method was, including a public client (section 4). Binding is not conditional on a per-client flag, because a bound token is never less safe than the unbound one it replaces, and a client that does not want binding does not present a certificate.

Implementations§

Source§

impl<'a> ClientCredential<'a>

Source

pub fn secret(client_secret: Option<&'a str>) -> Self

The credential of a client presenting a shared secret, or of a public client presenting none.

Source

pub fn assertion( client_assertion_type: Option<&'a str>, client_assertion: &'a str, ) -> Self

Available on crate feature client-assertion only.

The RFC 7523 credential: the assertion, and the type that names its format.

Source

pub fn certificate(certificate: &'a ClientCertificate<'a>) -> Self

Available on crate feature mtls only.

The RFC 8705 credential: the client certificate the host verified during the TLS handshake, and no secret at all.

For a client that authenticates some OTHER way and still wants its token bound (RFC 8705 section 4, including a public client), set ClientCredential::certificate on the credential it is already using rather than replacing it with this one.

Trait Implementations§

Source§

impl<'a> Clone for ClientCredential<'a>

Source§

fn clone(&self) -> ClientCredential<'a>

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<'a> Copy for ClientCredential<'a>

Source§

impl Debug for ClientCredential<'_>

Hand-written so neither the shared secret nor the assertion ever prints, in the same shape crate::token::TokenResponse uses: the Some/None distinction is KEPT, because WHICH credential a request presented is the diagnostic an operator actually needs and is not itself secret, while the value is. client_assertion_type prints in full: RFC 7521 section 4.2 makes it a fixed registered URN, so it identifies the mechanism rather than the holder. The certificate prints through its own Debug, which is a public document by construction.

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a> Default for ClientCredential<'a>

Source§

fn default() -> ClientCredential<'a>

Returns the “default value” for a type. Read more
Source§

impl<'a> Eq for ClientCredential<'a>

Source§

impl<'a> PartialEq for ClientCredential<'a>

Source§

fn eq(&self, other: &ClientCredential<'a>) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl<'a> StructuralPartialEq for ClientCredential<'a>

Auto Trait Implementations§

§

impl<'a> Freeze for ClientCredential<'a>

§

impl<'a> RefUnwindSafe for ClientCredential<'a>

§

impl<'a> Send for ClientCredential<'a>

§

impl<'a> Sync for ClientCredential<'a>

§

impl<'a> Unpin for ClientCredential<'a>

§

impl<'a> UnsafeUnpin for ClientCredential<'a>

§

impl<'a> UnwindSafe for ClientCredential<'a>

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<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

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> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.