openid_client/issuer/
jwks.rs1use std::{
4 collections::{hash_map::DefaultHasher, HashMap},
5 hash::{Hash, Hasher},
6};
7
8use serde_json::Value;
9
10use crate::{
11 issuer::Issuer,
12 jwks::Jwks,
13 types::{query_keystore::QueryKeyStore, OidcClientError, OidcHttpClient, OidcReturnType},
14};
15
16impl Issuer {
18 pub(crate) async fn query_keystore_async<T>(
19 &mut self,
20 mut query: QueryKeyStore,
21 allow_multi: bool,
22 http_client: &T,
23 ) -> OidcReturnType<Jwks>
24 where
25 T: OidcHttpClient,
26 {
27 let mut hasher = DefaultHasher::new();
28 query.hash(&mut hasher);
29 let hash = hasher.finish();
30
31 match &mut self.keystore {
32 Some(keystore) => {
33 let reload = keystore.cache.contains_key(&hash)
34 || (self.now)() - keystore.last_accessed > 60;
35
36 let jwks = keystore.get_keystore_async(reload, http_client).await?;
37
38 let keys = jwks.get(
39 query.alg.clone(),
40 query.key_use.clone(),
41 query.key_id.clone(),
42 )?;
43
44 let alg = query.alg.clone();
45
46 query.alg = None;
48
49 if keys.is_empty() {
50 let message = format!("no valid key found in issuer\'s jwks_uri for key parameters kid: {}, alg: {}, key_use: {}", query.key_id.unwrap_or("".to_string()), alg.unwrap_or("".to_string()), query.key_use.unwrap_or("".to_string()));
51
52 return Err(Box::new(OidcClientError::new_rp_error(&message, None)));
53 }
54
55 if !allow_multi && keys.len() > 1 && query.key_id.is_none() {
56 let message = format!("multiple matching keys found in issuer\'s jwks_uri for key parameters kid: {}, key_use: {}, alg: {}, kid must be provided in this case", query.key_id.unwrap_or("".to_string()), query.key_use.unwrap_or("".to_string()), alg.unwrap_or("".to_string()));
57
58 let mut extra_data = HashMap::<String, Value>::new();
59
60 let json_jwks = match serde_json::to_value(&jwks) {
61 Ok(v) => v,
62 Err(_) => {
63 return Err(Box::new(OidcClientError::new_error(
64 "Malformed jwks",
65 None,
66 )))
67 }
68 };
69
70 extra_data.insert("jwks".to_string(), json_jwks);
71
72 return Err(Box::new(OidcClientError::new_rp_error(&message, None)));
73 }
74
75 keystore.cache.insert(hash, true);
76
77 Ok(jwks)
78 }
79 _ => Err(Box::new(OidcClientError::new_error(
80 "No Keystore found for this issuer",
81 None,
82 ))),
83 }
84 }
85
86 pub async fn reload_jwks_async<T>(&mut self, http_client: &T) -> OidcReturnType<bool>
90 where
91 T: OidcHttpClient,
92 {
93 match &mut self.keystore {
94 Some(keystore) => {
95 keystore.get_keystore_async(true, http_client).await?;
96 Ok(true)
97 }
98 _ => Err(Box::new(OidcClientError::new_error(
99 "No Keystore found for this issuer",
100 None,
101 ))),
102 }
103 }
104}