1use std::{collections::HashMap, time::Duration};
2
3use serde_json::Value;
4
5use crate::{
6 helpers::{convert_json_to, now, validate_url},
7 http::request_async,
8 issuer::Issuer,
9 jwks::Jwks,
10 types::{
11 http_client::HttpMethod, ClientMetadata, ClientOptions, ClientRegistrationOptions, Fapi,
12 HttpRequest, OidcClientError, OidcHttpClient, OidcReturnType,
13 },
14};
15
16use super::dpop_nonce_cache::DPoPNonceCache;
17
18#[derive(Debug)]
20pub struct Client {
21 pub(crate) client_id: String,
22 pub(crate) client_secret: Option<String>,
23 pub(crate) registration_access_token: Option<String>,
24 pub(crate) registration_client_uri: Option<String>,
25 pub(crate) client_id_issued_at: Option<i64>,
26 pub(crate) client_secret_expires_at: Option<i64>,
27 pub(crate) token_endpoint_auth_method: Option<String>,
28 pub(crate) token_endpoint_auth_signing_alg: Option<String>,
29 pub(crate) introspection_endpoint_auth_method: Option<String>,
30 pub(crate) introspection_endpoint_auth_signing_alg: Option<String>,
31 pub(crate) revocation_endpoint_auth_method: Option<String>,
32 pub(crate) revocation_endpoint_auth_signing_alg: Option<String>,
33 pub(crate) redirect_uri: Option<String>,
34 pub(crate) redirect_uris: Option<Vec<String>>,
35 pub(crate) response_type: Option<String>,
36 pub(crate) response_types: Vec<String>,
37 pub(crate) grant_types: Vec<String>,
38 pub(crate) jwks_uri: Option<String>,
39 pub(crate) jwks: Option<Jwks>,
40 pub(crate) sector_identifier_uri: Option<String>,
41 pub(crate) subject_type: Option<String>,
42 pub(crate) id_token_signed_response_alg: String,
43 pub(crate) id_token_encrypted_response_alg: Option<String>,
44 pub(crate) id_token_encrypted_response_enc: Option<String>,
45 pub(crate) userinfo_signed_response_alg: Option<String>,
46 pub(crate) userinfo_encrypted_response_alg: Option<String>,
47 pub(crate) userinfo_encrypted_response_enc: Option<String>,
48 pub(crate) request_object_signing_alg: Option<String>,
49 pub(crate) request_object_encryption_alg: Option<String>,
50 pub(crate) request_object_encryption_enc: Option<String>,
51 pub(crate) default_max_age: Option<u64>,
52 pub(crate) require_auth_time: Option<bool>,
53 pub(crate) default_acr_values: Option<Vec<String>>,
54 pub(crate) initiate_login_uri: Option<String>,
55 pub(crate) request_uris: Option<String>,
56 pub(crate) tls_client_certificate_bound_access_tokens: Option<bool>,
57 pub(crate) post_logout_redirect_uris: Option<Vec<String>>,
58 pub(crate) authorization_encrypted_response_alg: Option<String>,
59 pub(crate) authorization_encrypted_response_enc: Option<String>,
60 pub(crate) authorization_signed_response_alg: Option<String>,
61 pub(crate) private_jwks: Option<Jwks>,
62 pub(crate) issuer: Option<Issuer>,
63 pub(crate) client_options: Option<ClientOptions>,
64 pub(crate) skip_max_age_check: bool,
65 pub(crate) skip_nonce_check: bool,
66 pub(crate) clock_tolerance: Duration,
67 pub(crate) fapi: Option<Fapi>,
68 pub(crate) now: fn() -> i64,
69 pub(crate) dpop_nonce_cache: DPoPNonceCache,
70 pub(crate) dpop_bound_access_tokens: Option<bool>,
71 pub(crate) other_fields: HashMap<String, Value>,
72}
73
74impl Client {
75 pub(crate) fn default(fapi: Option<Fapi>) -> Self {
76 let mut client = Self {
77 client_id: String::new(),
78 client_secret: None,
79 registration_access_token: None,
80 registration_client_uri: None,
81 client_id_issued_at: None,
82 client_secret_expires_at: None,
83 token_endpoint_auth_method: Some("client_secret_basic".to_string()),
84 token_endpoint_auth_signing_alg: None,
85 introspection_endpoint_auth_method: None,
86 introspection_endpoint_auth_signing_alg: None,
87 revocation_endpoint_auth_method: None,
88 revocation_endpoint_auth_signing_alg: None,
89 redirect_uri: None,
90 redirect_uris: None,
91 response_type: None,
92 response_types: vec!["code".to_string()],
93 grant_types: vec!["authorization_code".to_string()],
94 jwks_uri: None,
95 jwks: None,
96 sector_identifier_uri: None,
97 subject_type: None,
98 id_token_signed_response_alg: "RS256".to_string(),
99 id_token_encrypted_response_alg: None,
100 id_token_encrypted_response_enc: Some("A128CBC-HS256".to_string()),
101 userinfo_signed_response_alg: None,
102 userinfo_encrypted_response_alg: None,
103 userinfo_encrypted_response_enc: None,
104 request_object_signing_alg: None,
105 request_object_encryption_alg: None,
106 request_object_encryption_enc: None,
107 default_max_age: None,
108 require_auth_time: None,
109 default_acr_values: None,
110 initiate_login_uri: None,
111 request_uris: None,
112 private_jwks: None,
113 issuer: None,
114 tls_client_certificate_bound_access_tokens: None,
115 post_logout_redirect_uris: None,
116 authorization_encrypted_response_alg: None,
117 authorization_encrypted_response_enc: None,
118 authorization_signed_response_alg: None,
119 other_fields: HashMap::new(),
120 client_options: None,
121 skip_max_age_check: false,
122 skip_nonce_check: false,
123 clock_tolerance: Duration::from_secs(0),
124 fapi: None,
125 now,
126 dpop_nonce_cache: DPoPNonceCache::new(),
127 dpop_bound_access_tokens: None,
128 };
129
130 match fapi.as_ref() {
131 Some(Fapi::V1) => {
132 client.grant_types = vec!["authorization_code".to_string(), "implicit".to_string()];
133 client.id_token_signed_response_alg = "PS256".to_string();
134 client.authorization_signed_response_alg = Some("PS256".to_string());
135 client.response_types = vec!["code".to_string(), "id_token".to_string()];
136 client.tls_client_certificate_bound_access_tokens = Some(true);
137 client.token_endpoint_auth_method = None;
138 }
139 Some(Fapi::V2) => {
140 client.id_token_signed_response_alg = "PS256".to_string();
141 client.authorization_signed_response_alg = Some("PS256".to_string());
142 client.token_endpoint_auth_method = None;
143 }
144 None => {}
145 };
146
147 client.fapi = fapi;
148
149 client
150 }
151
152 pub(crate) fn from_internal(
153 metadata: ClientMetadata,
154 issuer: Option<&Issuer>,
155 jwks: Option<Jwks>,
156 options: Option<ClientOptions>,
157 fapi: Option<Fapi>,
158 ) -> OidcReturnType<Self> {
159 let mut valid_client_id = true;
160
161 if let Some(client_id) = &metadata.client_id {
162 if client_id.is_empty() {
163 valid_client_id = false;
164 }
165 } else {
166 valid_client_id = false;
167 }
168
169 if !valid_client_id {
170 return Err(Box::new(OidcClientError::new_type_error(
171 "client_id is required",
172 None,
173 )));
174 }
175
176 let mut client = Self {
177 client_id: metadata.client_id.unwrap(),
178 client_secret: metadata.client_secret,
179 sector_identifier_uri: metadata.sector_identifier_uri,
180 subject_type: metadata.subject_type,
181 registration_access_token: metadata.registration_access_token,
182 registration_client_uri: metadata.registration_client_uri,
183 client_id_issued_at: metadata.client_id_issued_at,
184 client_secret_expires_at: metadata.client_secret_expires_at,
185 id_token_encrypted_response_alg: metadata.id_token_encrypted_response_alg,
186 userinfo_signed_response_alg: metadata.userinfo_signed_response_alg,
187 userinfo_encrypted_response_alg: metadata.userinfo_encrypted_response_alg,
188 userinfo_encrypted_response_enc: metadata.userinfo_encrypted_response_enc,
189 request_object_signing_alg: metadata.request_object_signing_alg,
190 request_object_encryption_alg: metadata.request_object_encryption_alg,
191 request_object_encryption_enc: metadata.request_object_encryption_enc,
192 jwks_uri: metadata.jwks_uri,
193 jwks: metadata.jwks,
194 default_max_age: metadata.default_max_age,
195 require_auth_time: metadata.require_auth_time,
196 default_acr_values: metadata.default_acr_values,
197 initiate_login_uri: metadata.initiate_login_uri,
198 request_uris: metadata.request_uris,
199 post_logout_redirect_uris: metadata.post_logout_redirect_uris,
200 authorization_encrypted_response_alg: metadata.authorization_encrypted_response_alg,
201 authorization_encrypted_response_enc: metadata.authorization_encrypted_response_enc,
202 dpop_bound_access_tokens: metadata.dpop_bound_access_tokens,
203 other_fields: metadata.other_fields,
204 ..Client::default(fapi)
205 };
206
207 if metadata
208 .tls_client_certificate_bound_access_tokens
209 .is_some()
210 {
211 client.tls_client_certificate_bound_access_tokens =
212 metadata.tls_client_certificate_bound_access_tokens;
213 }
214
215 if metadata.authorization_signed_response_alg.is_some() {
216 client.authorization_signed_response_alg = metadata.authorization_signed_response_alg;
217 }
218
219 client.client_options = options;
220
221 if client.jwks_uri.is_some() && client.jwks.is_some() {
222 client.jwks = None;
223 }
224
225 if metadata.response_type.is_some() && metadata.response_types.is_some() {
226 return Err(Box::new(OidcClientError::new_type_error(
227 "provide a response_type or response_types, not both",
228 None,
229 )));
230 }
231
232 if let Some(response_type) = &metadata.response_type {
233 client.response_type = Some(response_type.clone());
234 client.response_types = vec![response_type.clone()];
235 }
236
237 if let Some(response_types) = &metadata.response_types {
238 client.response_types = response_types.clone().to_vec();
239 }
240
241 if metadata.redirect_uri.is_some() && metadata.redirect_uris.is_some() {
242 return Err(Box::new(OidcClientError::new_type_error(
243 "provide a redirect_uri or redirect_uris, not both",
244 None,
245 )));
246 }
247
248 if let Some(redirect_uri) = &metadata.redirect_uri {
249 client.redirect_uri = Some(redirect_uri.clone());
250 client.redirect_uris = Some(vec![redirect_uri.clone()])
251 }
252
253 if let Some(redirect_uris) = &metadata.redirect_uris {
254 client.redirect_uris = Some(redirect_uris.clone().to_vec());
255 }
256
257 if let Some(team) = metadata.token_endpoint_auth_method {
258 client.token_endpoint_auth_method = Some(team);
259 } else if let Some(iss) = issuer {
260 if let Some(teams) = &iss.token_endpoint_auth_methods_supported {
261 if let Some(team) = &client.token_endpoint_auth_method {
262 if !teams.contains(team) && teams.contains(&"client_secret_post".to_string()) {
263 client.token_endpoint_auth_method = Some("client_secret_post".to_string());
264 }
265 }
266 }
267 }
268
269 if metadata.token_endpoint_auth_signing_alg.is_some() {
270 client.token_endpoint_auth_signing_alg = metadata.token_endpoint_auth_signing_alg;
271 }
272
273 client.introspection_endpoint_auth_method = metadata
274 .introspection_endpoint_auth_method
275 .or(client.token_endpoint_auth_method.clone());
276
277 client.introspection_endpoint_auth_signing_alg = metadata
278 .introspection_endpoint_auth_signing_alg
279 .or(client.token_endpoint_auth_signing_alg.clone());
280
281 client.revocation_endpoint_auth_method = metadata
282 .revocation_endpoint_auth_method
283 .or(client.token_endpoint_auth_method.clone());
284
285 client.revocation_endpoint_auth_signing_alg = metadata
286 .revocation_endpoint_auth_signing_alg
287 .or(client.token_endpoint_auth_signing_alg.clone());
288
289 if let Some(iss) = issuer {
290 if iss.token_endpoint.is_some() {
291 Self::assert_signing_alg_values_support(
292 &client.token_endpoint_auth_method.clone(),
293 &client.token_endpoint_auth_signing_alg,
294 &iss.token_endpoint_auth_signing_alg_values_supported,
295 "token",
296 )?;
297 }
298
299 if iss.introspection_endpoint.is_some() {
300 Self::assert_signing_alg_values_support(
301 &client.introspection_endpoint_auth_method,
302 &client.introspection_endpoint_auth_signing_alg,
303 &iss.token_endpoint_auth_signing_alg_values_supported,
304 "introspection",
305 )?;
306 }
307
308 if iss.revocation_endpoint.is_some() {
309 Self::assert_signing_alg_values_support(
310 &client.revocation_endpoint_auth_method,
311 &client.revocation_endpoint_auth_signing_alg,
312 &iss.token_endpoint_auth_signing_alg_values_supported,
313 "revocation",
314 )?;
315 }
316
317 client.issuer = Some(iss.clone());
318 }
319
320 if metadata.id_token_encrypted_response_enc.is_some() {
321 client.id_token_encrypted_response_enc = metadata.id_token_encrypted_response_enc;
322 }
323
324 if jwks.is_some() {
325 client.private_jwks = jwks;
326 }
327
328 if let Some(alg) = metadata.id_token_signed_response_alg {
329 client.id_token_signed_response_alg = alg;
330 }
331
332 if client.is_fapi1() {
333 match client.token_endpoint_auth_method.as_deref() {
334 Some("private_key_jwt") => {
335 if client.private_jwks.is_none() {
336 return Err(Box::new(OidcClientError::new_type_error(
337 "jwks is required",
338 None,
339 )));
340 }
341 }
342 Some("self_signed_tls_client_auth") | Some("tls_client_auth") => {}
343 Some(_) => {
344 return Err(Box::new(OidcClientError::new_type_error(
345 "invalid or unsupported token_endpoint_auth_method",
346 None,
347 )));
348 }
349 None => {
350 return Err(Box::new(OidcClientError::new_type_error(
351 "token_endpoint_auth_method is required",
352 None,
353 )));
354 }
355 };
356 }
357
358 if client.is_fapi2() {
359 match (
360 client.tls_client_certificate_bound_access_tokens.as_ref(),
361 client.dpop_bound_access_tokens.as_ref(),
362 ) {
363 (Some(&false), Some(&false))
364 | (Some(&false), None)
365 | (None, Some(&false))
366 | (None, None) => return Err(Box::new(OidcClientError::new_type_error(
367 "one of tls_client_certificate_bound_access_tokens or dpop_bound_access_tokens must be true",
368 None,
369 ))),
370
371 (Some(&true), Some(&true)) => return Err(Box::new(OidcClientError::new_type_error(
372 "only one of tls_client_certificate_bound_access_tokens or dpop_bound_access_tokens must be true",
373 None,
374 ))),
375
376 (_, _) => {}
377 };
378 }
379
380 Ok(client)
381 }
382
383 fn assert_signing_alg_values_support(
384 auth_method: &Option<String>,
385 supported_alg: &Option<String>,
386 issuer_supported_alg_values: &Option<Vec<String>>,
387 endpoint: &str,
388 ) -> OidcReturnType<()> {
389 if let Some(am) = auth_method {
390 if am.ends_with("_jwt")
391 && supported_alg.is_none()
392 && issuer_supported_alg_values.is_none()
393 {
394 return Err(Box::new(OidcClientError::new_type_error(
395 &format!("{endpoint}_endpoint_auth_signing_alg_values_supported must be configured on the issuer if {endpoint}_endpoint_auth_signing_alg is not defined on a client"),
396 None,
397 )));
398 }
399 }
400 Ok(())
401 }
402
403 pub fn get_other_fields(&self) -> &HashMap<String, Value> {
405 &self.other_fields
406 }
407}
408
409impl Client {
411 pub async fn from_uri_async<T>(
423 http_client: &T,
424 registration_client_uri: &str,
425 issuer: &Issuer,
426 registration_access_token: Option<String>,
427 jwks: Option<Jwks>,
428 client_options: Option<ClientOptions>,
429 fapi: Option<Fapi>,
430 ) -> OidcReturnType<Self>
431 where
432 T: OidcHttpClient,
433 {
434 Self::jwks_only_private_keys_validation(jwks.as_ref())?;
435
436 let url = validate_url(registration_client_uri)?;
437
438 let mut headers = HashMap::new();
439 headers.insert("accept".to_string(), vec!["application/json".to_string()]);
440
441 if let Some(rat) = registration_access_token {
442 headers.insert("authorization".to_string(), vec![format!("Bearer {rat}")]);
443 }
444
445 let req = HttpRequest::new()
446 .url(url)
447 .method(HttpMethod::GET)
448 .expect_body(true)
449 .expect_status_code(200)
450 .expect_bearer(true)
451 .headers(headers);
452
453 let res = request_async(req, http_client).await?;
454
455 let client_metadata = convert_json_to::<ClientMetadata>(res.body.as_ref().unwrap())
456 .map_err(|_| {
457 OidcClientError::new_op_error(
458 "invalid client metadata".to_string(),
459 Some("error while deserializing".to_string()),
460 None,
461 Some(res),
462 )
463 })?;
464
465 Self::from_internal(client_metadata, Some(issuer), jwks, client_options, fapi)
466 }
467}
468
469impl Client {
471 pub async fn register_async<T>(
481 http_client: &T,
482 issuer: &Issuer,
483 mut client_metadata: ClientMetadata,
484 register_options: Option<ClientRegistrationOptions>,
485 fapi: Option<Fapi>,
486 ) -> OidcReturnType<Self>
487 where
488 T: OidcHttpClient,
489 {
490 if issuer.registration_endpoint.is_none() {
491 return Err(Box::new(OidcClientError::new_type_error(
492 "registration_endpoint must be configured on the issuer",
493 None,
494 )));
495 }
496
497 let mut initial_access_token: Option<String> = None;
498 let mut jwks: Option<Jwks> = None;
499 let mut client_options: Option<ClientOptions> = None;
500
501 if let Some(options) = ®ister_options {
502 initial_access_token.clone_from(&options.initial_access_token);
503 jwks.clone_from(&options.jwks);
504 client_options = Some(options.client_options.clone());
505
506 if options.jwks.is_some()
507 && client_metadata.jwks_uri.is_none()
508 && client_metadata.jwks.is_none()
509 {
510 if let Some(jwks) = options.jwks.as_ref() {
511 client_metadata.jwks = Some(jwks.get_public_jwks());
512 }
513 }
514 }
515
516 Self::jwks_only_private_keys_validation(jwks.as_ref())?;
517
518 let url = validate_url(issuer.registration_endpoint.as_ref().unwrap())?;
519
520 let body = serde_json::to_string(&client_metadata).map_err(|_| {
521 OidcClientError::new_error("client metadata is an invalid json format", None)
522 })?;
523
524 let mut headers = HashMap::new();
525 headers.insert("accept".to_string(), vec!["application/json".to_string()]);
526
527 if let Some(iat) = initial_access_token {
528 headers.insert("authorization".to_string(), vec![format!("Bearer {iat}")]);
529 }
530
531 let req = HttpRequest::new()
532 .url(url)
533 .method(HttpMethod::POST)
534 .expect_body(true)
535 .expect_status_code(201)
536 .expect_bearer(true)
537 .headers(headers)
538 .json(body);
539
540 let response = request_async(req, http_client).await?;
541
542 let client_metadata = convert_json_to::<ClientMetadata>(response.body.as_ref().unwrap())
543 .map_err(|_| {
544 OidcClientError::new_op_error(
545 "invalid client metadata".to_string(),
546 None,
547 None,
548 Some(response),
549 )
550 })?;
551
552 Self::from_internal(client_metadata, Some(issuer), jwks, client_options, fapi)
553 }
554
555 pub fn metadata(&self) -> ClientMetadata {
558 ClientMetadata {
559 client_id: Some(self.client_id.clone()),
560 client_secret: self.client_secret.clone(),
561 registration_access_token: self.registration_access_token.clone(),
562 registration_client_uri: self.registration_client_uri.clone(),
563 client_id_issued_at: self.client_id_issued_at,
564 client_secret_expires_at: self.client_secret_expires_at,
565 token_endpoint_auth_method: self.token_endpoint_auth_method.clone(),
566 token_endpoint_auth_signing_alg: self.token_endpoint_auth_signing_alg.clone(),
567 introspection_endpoint_auth_method: self.introspection_endpoint_auth_method.clone(),
568 introspection_endpoint_auth_signing_alg: self
569 .introspection_endpoint_auth_signing_alg
570 .clone(),
571 revocation_endpoint_auth_method: self.revocation_endpoint_auth_method.clone(),
572 revocation_endpoint_auth_signing_alg: self.revocation_endpoint_auth_signing_alg.clone(),
573 redirect_uri: self.redirect_uri.clone(),
574 redirect_uris: self.redirect_uris.clone(),
575 response_type: self.response_type.clone(),
576 response_types: Some(self.response_types.clone()),
577 grant_types: Some(self.grant_types.clone()),
578 jwks_uri: self.jwks_uri.clone(),
579 jwks: self.jwks.clone(),
580 sector_identifier_uri: self.sector_identifier_uri.clone(),
581 subject_type: self.subject_type.clone(),
582 id_token_signed_response_alg: Some(self.id_token_signed_response_alg.clone()),
583 id_token_encrypted_response_alg: self.id_token_encrypted_response_alg.clone(),
584 id_token_encrypted_response_enc: self.id_token_encrypted_response_enc.clone(),
585 userinfo_signed_response_alg: self.userinfo_signed_response_alg.clone(),
586 userinfo_encrypted_response_alg: self.userinfo_encrypted_response_alg.clone(),
587 userinfo_encrypted_response_enc: self.userinfo_encrypted_response_enc.clone(),
588 request_object_signing_alg: self.request_object_signing_alg.clone(),
589 request_object_encryption_alg: self.request_object_encryption_alg.clone(),
590 request_object_encryption_enc: self.request_object_encryption_enc.clone(),
591 default_max_age: self.default_max_age,
592 require_auth_time: self.require_auth_time,
593 default_acr_values: self.default_acr_values.clone(),
594 initiate_login_uri: self.initiate_login_uri.clone(),
595 request_uris: self.request_uris.clone(),
596 tls_client_certificate_bound_access_tokens: self
597 .tls_client_certificate_bound_access_tokens,
598 post_logout_redirect_uris: self.post_logout_redirect_uris.clone(),
599 authorization_signed_response_alg: self.authorization_signed_response_alg.clone(),
600 authorization_encrypted_response_alg: self.authorization_encrypted_response_alg.clone(),
601 authorization_encrypted_response_enc: self.authorization_encrypted_response_enc.clone(),
602 dpop_bound_access_tokens: self.dpop_bound_access_tokens,
603 other_fields: self.other_fields.clone(),
604 }
605 }
606
607 pub(crate) fn jwks_only_private_keys_validation(jwks: Option<&Jwks>) -> OidcReturnType<()> {
609 if let Some(jwks) = jwks {
610 if !jwks.is_only_private_keys() || jwks.has_oct_keys() {
611 return Err(Box::new(OidcClientError::new_error(
612 "jwks must only contain private keys",
613 None,
614 )));
615 }
616 }
617 Ok(())
618 }
619}
620
621impl Clone for Client {
622 fn clone(&self) -> Self {
623 Self {
624 client_id: self.client_id.clone(),
625 client_secret: self.client_secret.clone(),
626 registration_access_token: self.registration_access_token.clone(),
627 registration_client_uri: self.registration_client_uri.clone(),
628 client_id_issued_at: self.client_id_issued_at,
629 client_secret_expires_at: self.client_secret_expires_at,
630 token_endpoint_auth_method: self.token_endpoint_auth_method.clone(),
631 token_endpoint_auth_signing_alg: self.token_endpoint_auth_signing_alg.clone(),
632 introspection_endpoint_auth_method: self.introspection_endpoint_auth_method.clone(),
633 introspection_endpoint_auth_signing_alg: self
634 .introspection_endpoint_auth_signing_alg
635 .clone(),
636 revocation_endpoint_auth_method: self.revocation_endpoint_auth_method.clone(),
637 revocation_endpoint_auth_signing_alg: self.revocation_endpoint_auth_signing_alg.clone(),
638 redirect_uri: self.redirect_uri.clone(),
639 redirect_uris: self.redirect_uris.clone(),
640 response_type: self.response_type.clone(),
641 response_types: self.response_types.clone(),
642 grant_types: self.grant_types.clone(),
643 jwks_uri: self.jwks_uri.clone(),
644 jwks: self.jwks.clone(),
645 sector_identifier_uri: self.sector_identifier_uri.clone(),
646 subject_type: self.subject_type.clone(),
647 id_token_signed_response_alg: self.id_token_signed_response_alg.clone(),
648 id_token_encrypted_response_alg: self.id_token_encrypted_response_alg.clone(),
649 id_token_encrypted_response_enc: self.id_token_encrypted_response_enc.clone(),
650 userinfo_signed_response_alg: self.userinfo_signed_response_alg.clone(),
651 userinfo_encrypted_response_alg: self.userinfo_encrypted_response_alg.clone(),
652 userinfo_encrypted_response_enc: self.userinfo_encrypted_response_enc.clone(),
653 request_object_signing_alg: self.request_object_signing_alg.clone(),
654 request_object_encryption_alg: self.request_object_encryption_alg.clone(),
655 request_object_encryption_enc: self.request_object_encryption_enc.clone(),
656 default_max_age: self.default_max_age,
657 require_auth_time: self.require_auth_time,
658 default_acr_values: self.default_acr_values.clone(),
659 initiate_login_uri: self.initiate_login_uri.clone(),
660 request_uris: self.request_uris.clone(),
661 tls_client_certificate_bound_access_tokens: self
662 .tls_client_certificate_bound_access_tokens,
663 post_logout_redirect_uris: self.post_logout_redirect_uris.clone(),
664 authorization_encrypted_response_alg: self.authorization_encrypted_response_alg.clone(),
665 authorization_encrypted_response_enc: self.authorization_encrypted_response_enc.clone(),
666 authorization_signed_response_alg: self.authorization_signed_response_alg.clone(),
667 other_fields: self.other_fields.clone(),
668 private_jwks: self.private_jwks.clone(),
669 issuer: self.issuer.clone(),
670 client_options: self.client_options.clone(),
671 skip_max_age_check: self.skip_max_age_check,
672 skip_nonce_check: self.skip_nonce_check,
673 clock_tolerance: self.clock_tolerance,
674 fapi: self.fapi.clone(),
675 now: self.now,
676 dpop_nonce_cache: self.dpop_nonce_cache.clone(),
677 dpop_bound_access_tokens: self.dpop_bound_access_tokens,
678 }
679 }
680}
681
682#[cfg(test)]
683#[path = "../tests/client/mod.rs"]
684mod client_test;