@@ -274,72 +274,109 @@ pub(crate) async fn handler(
274274 )
275275 . await ?;
276276
277+ let mut jwks = None ;
278+
277279 let mut context = AttributeMappingContext :: new ( ) ;
278280 if let Some ( id_token) = token_response. id_token . as_ref ( ) {
279- // Fetch the JWKS
280- let jwks =
281- mas_oidc_client:: requests:: jose:: fetch_jwks ( & client, lazy_metadata. jwks_uri ( ) . await ?)
282- . await ?;
283-
284- let verification_data = JwtVerificationData {
285- issuer : & provider. issuer ,
286- jwks : & jwks,
287- // TODO: make that configurable
288- signing_algorithm : & mas_iana:: jose:: JsonWebSignatureAlg :: Rs256 ,
289- client_id : & provider. client_id ,
290- } ;
291-
292- // Decode and verify the ID token
293- let id_token = mas_oidc_client:: requests:: jose:: verify_id_token (
294- id_token,
295- verification_data,
296- None ,
297- clock. now ( ) ,
298- ) ?;
299-
300- let ( _headers, mut claims) = id_token. into_parts ( ) ;
301-
302- // Access token hash must match.
303- mas_jose:: claims:: AT_HASH
304- . extract_optional_with_options (
305- & mut claims,
306- TokenHash :: new (
307- verification_data. signing_algorithm ,
308- & token_response. access_token ,
309- ) ,
310- )
311- . map_err ( mas_oidc_client:: error:: IdTokenError :: from) ?;
312-
313- // Code hash must match.
314- mas_jose:: claims:: C_HASH
315- . extract_optional_with_options (
316- & mut claims,
317- TokenHash :: new ( verification_data. signing_algorithm , & code) ,
318- )
319- . map_err ( mas_oidc_client:: error:: IdTokenError :: from) ?;
320-
321- // Nonce must match.
322- mas_jose:: claims:: NONCE
323- . extract_required_with_options ( & mut claims, session. nonce . as_str ( ) )
324- . map_err ( mas_oidc_client:: error:: IdTokenError :: from) ?;
325-
326- context = context. with_id_token_claims ( claims) ;
281+ if let Some ( signed_response_alg) = & provider. id_token_signed_response_alg {
282+ jwks = Some (
283+ mas_oidc_client:: requests:: jose:: fetch_jwks (
284+ & client,
285+ lazy_metadata. jwks_uri ( ) . await ?,
286+ )
287+ . await ?,
288+ ) ;
289+
290+ let id_token_verification_data = JwtVerificationData {
291+ issuer : & provider. issuer ,
292+ jwks : & jwks. clone ( ) . unwrap ( ) ,
293+ signing_algorithm : signed_response_alg,
294+ client_id : & provider. client_id ,
295+ } ;
296+
297+ // Decode and verify the ID token
298+ let id_token = mas_oidc_client:: requests:: jose:: verify_id_token (
299+ id_token,
300+ id_token_verification_data,
301+ None ,
302+ clock. now ( ) ,
303+ ) ?;
304+
305+ let ( _headers, mut claims) = id_token. into_parts ( ) ;
306+
307+ // Access token hash must match.
308+ mas_jose:: claims:: AT_HASH
309+ . extract_optional_with_options (
310+ & mut claims,
311+ TokenHash :: new (
312+ id_token_verification_data. signing_algorithm ,
313+ & token_response. access_token ,
314+ ) ,
315+ )
316+ . map_err ( mas_oidc_client:: error:: IdTokenError :: from) ?;
317+
318+ // Code hash must match.
319+ mas_jose:: claims:: C_HASH
320+ . extract_optional_with_options (
321+ & mut claims,
322+ TokenHash :: new ( id_token_verification_data. signing_algorithm , & code) ,
323+ )
324+ . map_err ( mas_oidc_client:: error:: IdTokenError :: from) ?;
325+
326+ // Nonce must match.
327+ mas_jose:: claims:: NONCE
328+ . extract_required_with_options ( & mut claims, session. nonce . as_str ( ) )
329+ . map_err ( mas_oidc_client:: error:: IdTokenError :: from) ?;
330+
331+ context = context. with_id_token_claims ( claims) ;
332+ } else {
333+ let claims = serde_json:: from_str ( id_token)
334+ . map_err ( mas_oidc_client:: error:: IdTokenError :: from) ?;
335+ context = context. with_id_token_claims ( claims) ;
336+ }
327337 }
328338
329339 if let Some ( extra_callback_parameters) = extra_callback_parameters. clone ( ) {
330340 context = context. with_extra_callback_parameters ( extra_callback_parameters) ;
331341 }
332342
333343 let userinfo = if provider. fetch_userinfo {
334- Some ( json ! (
335- mas_oidc_client:: requests:: userinfo:: fetch_userinfo(
336- & client,
337- lazy_metadata. userinfo_endpoint( ) . await ?,
338- token_response. access_token. as_str( ) ,
339- None ,
340- )
341- . await ?
342- ) )
344+ Some ( json ! ( match & provider. userinfo_signed_response_alg {
345+ Some ( signing_algorithm) => {
346+ let jwks = match jwks {
347+ Some ( jwks) => jwks,
348+ None => {
349+ mas_oidc_client:: requests:: jose:: fetch_jwks(
350+ & client,
351+ lazy_metadata. jwks_uri( ) . await ?,
352+ )
353+ . await ?
354+ }
355+ } ;
356+
357+ mas_oidc_client:: requests:: userinfo:: fetch_userinfo(
358+ & client,
359+ lazy_metadata. userinfo_endpoint( ) . await ?,
360+ token_response. access_token. as_str( ) ,
361+ Some ( JwtVerificationData {
362+ issuer: & provider. issuer,
363+ jwks: & jwks,
364+ signing_algorithm,
365+ client_id: & provider. client_id,
366+ } ) ,
367+ )
368+ . await ?
369+ }
370+ None => {
371+ mas_oidc_client:: requests:: userinfo:: fetch_userinfo(
372+ & client,
373+ lazy_metadata. userinfo_endpoint( ) . await ?,
374+ token_response. access_token. as_str( ) ,
375+ None ,
376+ )
377+ . await ?
378+ }
379+ } ) )
343380 } else {
344381 None
345382 } ;
0 commit comments