#[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
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>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>client-assertion only.RFC 7523 section 2.2 client-assertion: the signed JWT itself.
certificate: Option<&'a ClientCertificate<'a>>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::Mtlsis authenticated by this certificate and by nothing else. Such a client cannot authenticate through a call that leaves thisNone, which is the point: a host that forgets to pass the certificate getsinvalid_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>
impl<'a> ClientCredential<'a>
Sourcepub fn secret(client_secret: Option<&'a str>) -> Self
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.
Sourcepub fn assertion(
client_assertion_type: Option<&'a str>,
client_assertion: &'a str,
) -> Self
Available on crate feature client-assertion only.
pub fn assertion( client_assertion_type: Option<&'a str>, client_assertion: &'a str, ) -> Self
client-assertion only.The RFC 7523 credential: the assertion, and the type that names its format.
Sourcepub fn certificate(certificate: &'a ClientCertificate<'a>) -> Self
Available on crate feature mtls only.
pub fn certificate(certificate: &'a ClientCertificate<'a>) -> Self
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>
impl<'a> Clone for ClientCredential<'a>
Source§fn clone(&self) -> ClientCredential<'a>
fn clone(&self) -> ClientCredential<'a>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl<'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.
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.