@@ -231,14 +231,65 @@ object OAuth2Login extends RestHelper with MdcLoggable {
231
231
def checkUrlOfJwkSets (identityProvider : String ) = {
232
232
val url : List [String ] = Constant .oauth2JwkSetUrl.toList
233
233
val jwksUris : List [String ] = url.map(_.toLowerCase()).map(_.split(" ," ).toList).flatten
234
-
234
+
235
+ logger.debug(s " checkUrlOfJwkSets - identityProvider: ' $identityProvider' " )
236
+ logger.debug(s " checkUrlOfJwkSets - oauth2.jwk_set.url raw value: ' ${Constant .oauth2JwkSetUrl}' " )
237
+ logger.debug(s " checkUrlOfJwkSets - parsed jwksUris: $jwksUris" )
238
+
235
239
// Enhanced matching for both URL-based and semantic identifiers
236
240
val identityProviderLower = identityProvider.toLowerCase()
237
241
val jwksUri = jwksUris.filter(_.contains(identityProviderLower))
238
-
242
+
243
+ logger.debug(s " checkUrlOfJwkSets - identityProviderLower: ' $identityProviderLower' " )
244
+ logger.debug(s " checkUrlOfJwkSets - filtered jwksUri: $jwksUri" )
245
+
239
246
jwksUri match {
240
- case x :: _ => Full (x)
241
- case Nil => Failure (Oauth2CannotMatchIssuerAndJwksUriException )
247
+ case x :: _ =>
248
+ logger.debug(s " checkUrlOfJwkSets - SUCCESS: Found matching JWKS URI: ' $x' " )
249
+ Full (x)
250
+ case Nil =>
251
+ logger.debug(s " checkUrlOfJwkSets - FAILURE: Cannot match issuer ' $identityProvider' with any JWKS URI " )
252
+ logger.debug(s " checkUrlOfJwkSets - Expected issuer pattern: ' $identityProvider' (case-insensitive contains match) " )
253
+ logger.debug(s " checkUrlOfJwkSets - Available JWKS URIs: $jwksUris" )
254
+ logger.debug(s " checkUrlOfJwkSets - Identity provider (lowercase): ' $identityProviderLower' " )
255
+ logger.debug(s " checkUrlOfJwkSets - Matching logic: Looking for JWKS URIs containing ' $identityProviderLower' " )
256
+ Failure (Oauth2CannotMatchIssuerAndJwksUriException )
257
+ }
258
+ }
259
+
260
+ def checkUrlOfJwkSetsWithToken (identityProvider : String , jwtToken : String ) = {
261
+ val actualIssuer = JwtUtil .getIssuer(jwtToken).getOrElse(" NO_ISSUER_CLAIM" )
262
+ val url : List [String ] = Constant .oauth2JwkSetUrl.toList
263
+ val jwksUris : List [String ] = url.map(_.toLowerCase()).map(_.split(" ," ).toList).flatten
264
+
265
+ logger.debug(s " checkUrlOfJwkSetsWithToken - Expected identity provider: ' $identityProvider' " )
266
+ logger.debug(s " checkUrlOfJwkSetsWithToken - Actual JWT issuer claim: ' $actualIssuer' " )
267
+ logger.debug(s " checkUrlOfJwkSetsWithToken - oauth2.jwk_set.url raw value: ' ${Constant .oauth2JwkSetUrl}' " )
268
+ logger.debug(s " checkUrlOfJwkSetsWithToken - parsed jwksUris: $jwksUris" )
269
+
270
+ // Enhanced matching for both URL-based and semantic identifiers
271
+ val identityProviderLower = identityProvider.toLowerCase()
272
+ val jwksUri = jwksUris.filter(_.contains(identityProviderLower))
273
+
274
+ logger.debug(s " checkUrlOfJwkSetsWithToken - identityProviderLower: ' $identityProviderLower' " )
275
+ logger.debug(s " checkUrlOfJwkSetsWithToken - filtered jwksUri: $jwksUri" )
276
+
277
+ jwksUri match {
278
+ case x :: _ =>
279
+ logger.debug(s " checkUrlOfJwkSetsWithToken - SUCCESS: Found matching JWKS URI: ' $x' " )
280
+ Full (x)
281
+ case Nil =>
282
+ logger.debug(s " checkUrlOfJwkSetsWithToken - FAILURE: Cannot match issuer with any JWKS URI " )
283
+ logger.debug(s " checkUrlOfJwkSetsWithToken - Expected identity provider: ' $identityProvider' " )
284
+ logger.debug(s " checkUrlOfJwkSetsWithToken - Actual JWT issuer claim: ' $actualIssuer' " )
285
+ logger.debug(s " checkUrlOfJwkSetsWithToken - Available JWKS URIs: $jwksUris" )
286
+ logger.debug(s " checkUrlOfJwkSetsWithToken - Expected pattern (lowercase): ' $identityProviderLower' " )
287
+ logger.debug(s " checkUrlOfJwkSetsWithToken - Matching logic: Looking for JWKS URIs containing ' $identityProviderLower' " )
288
+ logger.debug(s " checkUrlOfJwkSetsWithToken - TROUBLESHOOTING: " )
289
+ logger.debug(s " checkUrlOfJwkSetsWithToken - 1. Verify oauth2.jwk_set.url contains URL matching ' $identityProvider' " )
290
+ logger.debug(s " checkUrlOfJwkSetsWithToken - 2. Check if JWT issuer ' $actualIssuer' should match identity provider ' $identityProvider' " )
291
+ logger.debug(s " checkUrlOfJwkSetsWithToken - 3. Ensure case-insensitive substring matching works: does any JWKS URI contain ' $identityProviderLower'? " )
292
+ Failure (Oauth2CannotMatchIssuerAndJwksUriException )
242
293
}
243
294
}
244
295
@@ -259,14 +310,33 @@ object OAuth2Login extends RestHelper with MdcLoggable {
259
310
}.getOrElse(false )
260
311
}
261
312
def validateIdToken (idToken : String ): Box [IDTokenClaimsSet ] = {
313
+ logger.debug(s " validateIdToken - attempting to validate ID token " )
314
+
315
+ // Extract issuer for better error reporting
316
+ val actualIssuer = JwtUtil .getIssuer(idToken).getOrElse(" NO_ISSUER_CLAIM" )
317
+ logger.debug(s " validateIdToken - JWT issuer claim: ' $actualIssuer' " )
318
+
262
319
urlOfJwkSets match {
263
320
case Full (url) =>
321
+ logger.debug(s " validateIdToken - using JWKS URL: ' $url' " )
264
322
JwtUtil .validateIdToken(idToken, url)
265
323
case ParamFailure (a, b, c, apiFailure : APIFailure ) =>
324
+ logger.debug(s " validateIdToken - ParamFailure: $a, $b, $c, $apiFailure" )
325
+ logger.debug(s " validateIdToken - JWT issuer was: ' $actualIssuer' " )
266
326
ParamFailure (a, b, c, apiFailure : APIFailure )
267
327
case Failure (msg, t, c) =>
328
+ logger.debug(s " validateIdToken - Failure getting JWKS URL: $msg" )
329
+ logger.debug(s " validateIdToken - JWT issuer was: ' $actualIssuer' " )
330
+ if (msg.contains(" OBP-20208" )) {
331
+ logger.debug(" validateIdToken - OBP-20208 Error Details:" )
332
+ logger.debug(s " validateIdToken - JWT issuer claim: ' $actualIssuer' " )
333
+ logger.debug(s " validateIdToken - oauth2.jwk_set.url value: ' ${Constant .oauth2JwkSetUrl}' " )
334
+ logger.debug(" validateIdToken - Check that the JWKS URL configuration matches the JWT issuer" )
335
+ }
268
336
Failure (msg, t, c)
269
337
case _ =>
338
+ logger.debug(" validateIdToken - No JWKS URL available" )
339
+ logger.debug(s " validateIdToken - JWT issuer was: ' $actualIssuer' " )
270
340
Failure (Oauth2ThereIsNoUrlOfJwkSet )
271
341
}
272
342
}
@@ -414,19 +484,42 @@ object OAuth2Login extends RestHelper with MdcLoggable {
414
484
}
415
485
416
486
def applyIdTokenRules (token : String , cc : CallContext ): (Box [User ], Some [CallContext ]) = {
487
+ logger.debug(" applyIdTokenRules - starting ID token validation" )
488
+
489
+ // Extract issuer from token for debugging
490
+ val actualIssuer = JwtUtil .getIssuer(token).getOrElse(" NO_ISSUER_CLAIM" )
491
+ logger.debug(s " applyIdTokenRules - JWT issuer claim: ' $actualIssuer' " )
492
+
417
493
validateIdToken(token) match {
418
494
case Full (_) =>
495
+ logger.debug(" applyIdTokenRules - ID token validation successful" )
419
496
val user = getOrCreateResourceUser(token)
420
497
val consumer = getOrCreateConsumer(token, user.map(_.userId), Some (OpenIdConnect .openIdConnect))
421
498
LoginAttempt .userIsLocked(user.map(_.provider).getOrElse(" " ), user.map(_.name).getOrElse(" " )) match {
422
499
case true => ((Failure (UsernameHasBeenLocked ), Some (cc.copy(consumer = consumer))))
423
500
case false => (user, Some (cc.copy(consumer = consumer)))
424
501
}
425
502
case ParamFailure (a, b, c, apiFailure : APIFailure ) =>
503
+ logger.debug(s " applyIdTokenRules - ParamFailure during token validation: $a" )
504
+ logger.debug(s " applyIdTokenRules - JWT issuer was: ' $actualIssuer' " )
426
505
(ParamFailure (a, b, c, apiFailure : APIFailure ), Some (cc))
427
506
case Failure (msg, t, c) =>
507
+ logger.debug(s " applyIdTokenRules - Failure during token validation: $msg" )
508
+ logger.debug(s " applyIdTokenRules - JWT issuer was: ' $actualIssuer' " )
509
+ if (msg.contains(" OBP-20208" )) {
510
+ logger.debug(" applyIdTokenRules - OBP-20208: JWKS URI matching failed. Diagnostic info:" )
511
+ logger.debug(s " applyIdTokenRules - Actual JWT issuer: ' $actualIssuer' " )
512
+ logger.debug(s " applyIdTokenRules - oauth2.jwk_set.url config: ' ${Constant .oauth2JwkSetUrl}' " )
513
+ logger.debug(" applyIdTokenRules - Resolution steps:" )
514
+ logger.debug(" 1. Verify oauth2.jwk_set.url contains URLs that match the JWT issuer" )
515
+ logger.debug(" 2. Check if JWT issuer claim matches expected identity provider" )
516
+ logger.debug(" 3. Ensure case-insensitive substring matching works between issuer and JWKS URLs" )
517
+ logger.debug(" 4. Consider if trailing slashes or URL formatting might be causing mismatch" )
518
+ }
428
519
(Failure (msg, t, c), Some (cc))
429
520
case _ =>
521
+ logger.debug(" applyIdTokenRules - Unknown failure during token validation" )
522
+ logger.debug(s " applyIdTokenRules - JWT issuer was: ' $actualIssuer' " )
430
523
(Failure (Oauth2IJwtCannotBeVerified ), Some (cc))
431
524
}
432
525
}
0 commit comments