pub struct Issuer {
    pub introspection_endpoint: Option<String>,
    pub pushed_authorization_request_endpoint: Option<String>,
    pub require_pushed_authorization_requests: bool,
    /* private fields */
}
Expand description

Holds all the discovered values from the OIDC Issuer

Fields§

§introspection_endpoint: Option<String>§pushed_authorization_request_endpoint: Option<String>

The URL of the pushed authorization request endpoint at which client can post an authorization request to exchange for a “request_uri” value usable at the authorization server.

§require_pushed_authorization_requests: bool

Boolean parameter indicating whether the authorization server accepts authorization request data only via PAR. If omitted, the default value is “false”.

Implementations§

source§

impl Issuer

Issuer Instance Creation

source

pub fn new( metadata: IssuerMetadata, interceptor: Option<RequestInterceptor> ) -> Self

Issuer

Create an Issuer instance using IssuerMetadata.

No OIDC Discovery defaults are set if Issuer is created using this method.

If no introspection/revocation endpoint auth methods or algorithms are specified, value of token endpoint auth methods and algorithms are used as the the value for the said properties.

Example:
    let metadata = IssuerMetadata {
        issuer: "https://auth.example.com".to_string(),
        authorization_endpoint: Some("https://auth.example.com/authorize".to_string()),
        token_endpoint: Some("https://auth.example.com/token".to_string()),
        userinfo_endpoint: Some("https://auth.example.com/userinfo".to_string()),
        jwks_uri: Some("https://auth.example.com/certs".to_string()),
        ..IssuerMetadata::default()
    };

    let issuer = Issuer::new(metadata, None);
Example: with a request interceptor
    let metadata = IssuerMetadata {
        issuer: "https://auth.example.com".to_string(),
        authorization_endpoint: Some("https://auth.example.com/authorize".to_string()),
        token_endpoint: Some("https://auth.example.com/token".to_string()),
        userinfo_endpoint: Some("https://auth.example.com/userinfo".to_string()),
        jwks_uri: Some("https://auth.example.com/certs".to_string()),
        ..IssuerMetadata::default()
    };

   #[derive(Debug, Clone)]
   pub(crate) struct CustomInterceptor {
       pub some_header: String,
       pub some_header_value: String,
   }

   impl Interceptor for CustomInterceptor {
       fn intercept(&mut self, _req: &Request) -> RequestOptions {
           let mut headers: HeaderMap = HeaderMap::new();

           let header = HeaderName::from_bytes(self.some_header.as_bytes()).unwrap();
           let header_value = HeaderValue::from_bytes(self.some_header_value.as_bytes()).unwrap();

           headers.append(header, header_value);

           RequestOptions {
               headers,
               timeout: Duration::from_millis(5000),
               ..Default::default()
           }
       }

       fn clone_box(&self) -> Box<dyn Interceptor> {
           Box::new(CustomInterceptor {
               some_header: self.some_header.clone(),
               some_header_value: self.some_header_value.clone(),
           })
       }
   }

   let interceptor = CustomInterceptor {
       some_header: "foo".to_string(),
       some_header_value: "bar".to_string(),
   };

    let issuer = Issuer::new(metadata, Some(Box::new(interceptor)));

    // Get jwks request will send the header foo: bar in the request
    let _ = issuer.get_jwks();
source§

impl Issuer

source

pub async fn discover_async( issuer: &str, interceptor: Option<RequestInterceptor> ) -> Result<Issuer, OidcClientError>

Discover OIDC Issuer

Discover an OIDC Issuer using the issuer url.

Only an absolute urls are accepted, passing in auth.example.com will result in an error.

Example:
    let _ = Issuer::discover_async("https://auth.example.com", None)
        .await
        .unwrap();
Example: with .well-known/openid-configuration

Urls with .well-known/openid-configuration can also be used to discover issuer.

    let _ = Issuer::discover_async(
        "https://auth.example.com/.well-known/openid-configuration",
        None,
    )
    .await
    .unwrap();
Example: with interceptor

   #[derive(Debug, Clone)]
   pub(crate) struct CustomInterceptor {
       pub some_header: String,
       pub some_header_value: String,
   }

   impl Interceptor for CustomInterceptor {
       fn intercept(&mut self, _req: &Request) -> RequestOptions {
           let mut headers: HeaderMap = HeaderMap::new();

           let header = HeaderName::from_bytes(self.some_header.as_bytes()).unwrap();
           let header_value = HeaderValue::from_bytes(self.some_header_value.as_bytes()).unwrap();

           headers.append(header, header_value);

           RequestOptions {
               headers,
               timeout: Duration::from_millis(5000),
               ..Default::default()
           }
       }

       fn clone_box(&self) -> Box<dyn Interceptor> {
           Box::new(CustomInterceptor {
               some_header: self.some_header.clone(),
               some_header_value: self.some_header_value.clone(),
           })
       }
   }

   let interceptor = CustomInterceptor {
       some_header: "foo".to_string(),
       some_header_value: "bar".to_string(),
   };

    // The discovery request will send header foo: bar in the request headers

    let _ = Issuer::discover_async(
        "https://auth.example.com/.well-known/openid-configuration",
        Some(Box::new(interceptor)),
    )
    .await
    .unwrap();
source§

impl Issuer

source

pub async fn webfinger_async( input: &str, interceptor: Option<RequestInterceptor> ) -> Result<Issuer, OidcClientError>

Webfinger OIDC Issuer Discovery

Discover an OIDC Issuer using the user email, url, url with port syntax or acct syntax.

Example:
#[tokio::main]
async fn main() {
    let _issuer_email = Issuer::webfinger_async("joe@auth.example.com", None)
        .await
        .unwrap();
    let _issuer_url = Issuer::webfinger_async("https://auth.example.com/joe", None)
        .await
        .unwrap();
    let _issuer_url_port = Issuer::webfinger_async("auth.example.com:3000/joe", None)
        .await
        .unwrap();
    let _issuer_acct_email = Issuer::webfinger_async("acct:joe@auth.example.com", None)
        .await
        .unwrap();
    let _issuer_acct_host = Issuer::webfinger_async("acct:auth.example.com", None)
        .await
        .unwrap();
}
Example: with interceptor
    // This interceptor will insert a header foo: bar for the discovery request made
    // internally after webfinger request

   #[derive(Debug, Clone)]
   pub(crate) struct CustomInterceptor {
       pub some_header: String,
       pub some_header_value: String,
   }

   impl Interceptor for CustomInterceptor {
       fn intercept(&mut self, _req: &Request) -> RequestOptions {
           let mut headers: HeaderMap = HeaderMap::new();

           let header = HeaderName::from_bytes(self.some_header.as_bytes()).unwrap();
           let header_value = HeaderValue::from_bytes(self.some_header_value.as_bytes()).unwrap();

           headers.append(header, header_value);

           RequestOptions {
               headers,
               timeout: Duration::from_millis(5000),
               ..Default::default()
           }
       }

       fn clone_box(&self) -> Box<dyn Interceptor> {
           Box::new(CustomInterceptor {
               some_header: self.some_header.clone(),
               some_header_value: self.some_header_value.clone(),
           })
       }
   }

   let interceptor = CustomInterceptor {
       some_header: "foo".to_string(),
       some_header_value: "bar".to_string(),
   };

    let _issuer = Issuer::webfinger_async("joe@auth.example.com", Some(Box::new(interceptor)))
        .await
        .unwrap();
source§

impl Issuer

New Client implementation for Issuer

source

pub fn client( &self, metadata: ClientMetadata, interceptor: Option<RequestInterceptor>, jwks: Option<Jwks>, client_options: Option<ClientOptions>, is_fapi: bool ) -> Result<Client, OidcClientError>

Creates a client from the issuer

This method creates a new Client from the issuer. A client metadata with a required client_id field is also required

  • metadata - ClientMetadata
  • interceptor - RequestInterceptor
  • jwks - The client jwks with private keys.
  • client_options - Client options.
  • is_fapi - Marks the client as FAPI client

Note: If the Issuer already have a request interceptor and none was passed in through interceptor, the interceptor from the Issuer is used.

Example:
    let issuer = Issuer::discover("https://auth.example.com", None).unwrap();
     
    let client_metadata = ClientMetadata {
        client_id: Some("client_id".to_string()),
        ..ClientMetadata::default()
    };
     
    let _client = issuer.client(client_metadata, None, None, None, false).unwrap();
Example: with jwks
    let issuer = Issuer::discover("https://auth.example.com", None).unwrap();

    let client_metadata = ClientMetadata {
        client_id: Some("client_id".to_string()),
        ..ClientMetadata::default()
    };

    let jwk = jwk::Jwk::generate_rsa_key(2048).unwrap();

    let jwks = Jwks::from(vec![jwk]);

    let _client = issuer
        .client(client_metadata, None, Some(jwks), None, false)
        .unwrap();
Example: with all params
    let issuer = Issuer::discover("https://auth.example.com", None).unwrap();

    // Adds a foo: bar header for all urls that contains `userinfo`

   #[derive(Debug, Clone)]
   pub(crate) struct CustomInterceptor {
       pub some_header: String,
       pub some_header_value: String,
   }

   impl Interceptor for CustomInterceptor {
       fn intercept(&mut self, _req: &Request) -> RequestOptions {
           let mut headers: HeaderMap = HeaderMap::new();

           let header = HeaderName::from_bytes(self.some_header.as_bytes()).unwrap();
           let header_value = HeaderValue::from_bytes(self.some_header_value.as_bytes()).unwrap();

           headers.append(header, header_value);

           RequestOptions {
               headers,
               timeout: Duration::from_millis(5000),
               ..Default::default()
           }
       }

       fn clone_box(&self) -> Box<dyn Interceptor> {
           Box::new(CustomInterceptor {
               some_header: self.some_header.clone(),
               some_header_value: self.some_header_value.clone(),
           })
       }
   }

   let interceptor = CustomInterceptor {
       some_header: "foo".to_string(),
       some_header_value: "bar".to_string(),
   };

    let jwk = Jwk::generate_rsa_key(2048).unwrap();

    let jwks = Jwks::from(vec![jwk]);

    let client_options = ClientOptions {
        additional_authorized_parties: Some(vec!["authParty".to_string()]),
    };

    let client_metadata = ClientMetadata {
        client_id: Some("client_id".to_string()),
        ..ClientMetadata::default()
    };

    let _client = issuer
        .client(
        client_metadata,
        Some(Box::new(interceptor)),
        Some(jwks),
        Some(client_options),
        false)
        .unwrap();
source§

impl Issuer

source

pub fn get_issuer(&self) -> String

Get issuer

source

pub fn get_authorization_endpoint(&self) -> Option<String>

Get authorization endpoint

source

pub fn get_token_endpoint(&self) -> Option<String>

Get token endpoint

source

pub fn get_jwks_uri(&self) -> Option<String>

Get jwks uri

source

pub fn get_userinfo_endpoint(&self) -> Option<String>

Get userinfo endpoint

source

pub fn get_revocation_endpoint(&self) -> Option<String>

Get revocation endpoint

source

pub fn get_claims_parameter_supported(&self) -> Option<bool>

Get claims paramter supported

source

pub fn get_grant_types_supported(&self) -> Option<Vec<String>>

Get grant types supported

source

pub fn get_request_parameter_supported(&self) -> Option<bool>

Get request parameter supported

source

pub fn get_request_uri_parameter_supported(&self) -> Option<bool>

Get request uri parameter supported

source

pub fn get_require_request_uri_registration(&self) -> Option<bool>

Get require request uri registration

source

pub fn get_response_modes_supported(&self) -> Option<Vec<String>>

Get response modes supported

source

pub fn get_claim_types_supported(&self) -> Vec<String>

Get claim types supported

source

pub fn get_token_endpoint_auth_methods_supported(&self) -> Option<Vec<String>>

Get token endpoint auth methods supported

source

pub fn get_introspection_endpoint_auth_methods_supported( &self ) -> Option<Vec<String>>

Get introspection endpoint auth methods supported

source

pub fn get_introspection_endpoint_auth_signing_alg_values_supported( &self ) -> Option<Vec<String>>

Get introspection endpoint auth signing algorithm values supported

source

pub fn get_revocation_endpoint_auth_methods_supported( &self ) -> Option<Vec<String>>

Get revocation endpoint auth methods supported

source

pub fn get_revocation_endpoint_auth_signing_alg_values_supported( &self ) -> Option<Vec<String>>

Get revocation endpoint auth signing algorithm values supported

source

pub fn get_other_fields(&self) -> HashMap<String, Value>

Get other fields

source

pub async fn get_jwks(&mut self) -> Option<Jwks>

Get Jwks

source

pub fn get_registration_endpoint(&self) -> Option<String>

Get registration endpoint

source

pub fn get_authorization_response_iss_parameter_supported(&self) -> Option<bool>

Get authorization response issuer parameter supported

source

pub fn get_dpop_signing_alg_values_supported(&self) -> Option<Vec<String>>

Get DPoP alg valued supported

source

pub fn set_request_interceptor(&mut self, interceptor: RequestInterceptor)

source§

impl Issuer

Issuer’s Keystore methods

source

pub async fn reload_jwks_async(&mut self) -> Result<bool, OidcClientError>

Reload Issuer Jwks This method force refreshes the issuer Jwks using the configured Jwks Uri. If no jwks_uri is found, returns an OidcClientError.

Trait Implementations§

source§

impl Clone for Issuer

source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for Issuer

source§

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

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

impl Default for Issuer

source§

fn default() -> Self

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

Auto Trait Implementations§

§

impl !RefUnwindSafe for Issuer

§

impl !Send for Issuer

§

impl !Sync for Issuer

§

impl Unpin for Issuer

§

impl !UnwindSafe for Issuer

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

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

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

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 Twhere 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

§

type Output = T

Should always be Self
source§

impl<T> ToOwned for Twhere T: Clone,

§

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 Twhere U: Into<T>,

§

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 Twhere U: TryFrom<T>,

§

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.
§

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

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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