Extract scopes from the JWT claims using a dot-separated path. Handles two formats: - Space-delimited string: `"openid sandbox:read sandbox:write"` (Keycloak, Entra) - JSON array: `["sandbox:read", "sandbox:write"]` (Okta) Filters out standard OIDC scopes (`openid`, `profile`, `email`, `offline_access`).
(&self, scopes_claim: &str)
| 140 | /// |
| 141 | /// Filters out standard OIDC scopes (`openid`, `profile`, `email`, `offline_access`). |
| 142 | fn extract_scopes(&self, scopes_claim: &str) -> Vec<String> { |
| 143 | let mut value = &self.extra; |
| 144 | for segment in scopes_claim.split('.') { |
| 145 | match value.get(segment) { |
| 146 | Some(v) => value = v, |
| 147 | None => return vec![], |
| 148 | } |
| 149 | } |
| 150 | |
| 151 | let raw: Vec<String> = if let Some(s) = value.as_str() { |
| 152 | s.split_whitespace().map(String::from).collect() |
| 153 | } else if let Some(arr) = value.as_array() { |
| 154 | arr.iter() |
| 155 | .filter_map(|v| v.as_str().map(String::from)) |
| 156 | .collect() |
| 157 | } else { |
| 158 | return vec![]; |
| 159 | }; |
| 160 | |
| 161 | raw.into_iter() |
| 162 | .filter(|s| !STANDARD_OIDC_SCOPES.contains(&s.as_str())) |
| 163 | .collect() |
| 164 | } |
| 165 | } |
| 166 | |
| 167 | impl JwksCache { |