|
67 | 67 | import com.google.gson.JsonElement;
|
68 | 68 | import com.google.gson.JsonObject;
|
69 | 69 | import com.google.gson.JsonParser;
|
| 70 | +import com.nimbusds.jose.Algorithm; |
70 | 71 | import com.nimbusds.jose.JWSAlgorithm;
|
71 | 72 | import com.nimbusds.jose.JWSHeader;
|
72 | 73 | import com.nimbusds.jose.util.Base64;
|
| 74 | +import com.nimbusds.jwt.JWT; |
73 | 75 | import com.nimbusds.jwt.JWTClaimsSet;
|
| 76 | +import com.nimbusds.jwt.JWTParser; |
| 77 | +import com.nimbusds.jwt.PlainJWT; |
74 | 78 | import com.nimbusds.jwt.ReadOnlyJWTClaimsSet;
|
75 | 79 | import com.nimbusds.jwt.SignedJWT;
|
76 | 80 |
|
@@ -437,34 +441,57 @@ protected ClientHttpRequest createRequest(URI url, HttpMethod method) throws IOE
|
437 | 441 | }
|
438 | 442 |
|
439 | 443 | try {
|
440 |
| -SignedJWT idToken = SignedJWT.parse(idTokenValue); |
| 444 | +JWT idToken = JWTParser.parse(idTokenValue); |
441 | 445 |
|
442 | 446 | // validate our ID Token over a number of tests
|
443 | 447 | ReadOnlyJWTClaimsSet idClaims = idToken.getJWTClaimsSet();
|
444 | 448 |
|
445 | 449 | // check the signature
|
446 | 450 | JwtSigningAndValidationService jwtValidator = null;
|
447 | 451 |
|
448 |
| -JWSAlgorithm alg = idToken.getHeader().getAlgorithm(); |
449 |
| -if (alg.equals(JWSAlgorithm.HS256) |
450 |
| -|| alg.equals(JWSAlgorithm.HS384) |
451 |
| -|| alg.equals(JWSAlgorithm.HS512)) { |
452 |
| - |
453 |
| -// generate one based on client secret |
454 |
| -jwtValidator = symmetricCacheService.getSymmetricValidtor(clientConfig.getClient()); |
455 |
| -} else { |
456 |
| -// otherwise load from the server's public key |
457 |
| -jwtValidator = validationServices.getValidator(serverConfig.getJwksUri()); |
458 |
| -} |
| 452 | +Algorithm tokenAlg = idToken.getHeader().getAlgorithm(); |
459 | 453 |
|
460 |
| -if (jwtValidator != null) { |
461 |
| -if(!jwtValidator.validateSignature(idToken)) { |
462 |
| -throw new AuthenticationServiceException("Signature validation failed"); |
| 454 | +Algorithm clientAlg = clientConfig.getIdTokenSignedResponseAlg(); |
| 455 | + |
| 456 | +if (clientAlg != null) { |
| 457 | +if (!clientAlg.equals(tokenAlg)) { |
| 458 | +throw new AuthenticationServiceException("Token algorithm " + tokenAlg + " does not match expected algorithm " + clientAlg); |
463 | 459 | }
|
464 |
| -} else { |
465 |
| -logger.error("No validation service found. Skipping signature validation"); |
466 |
| -throw new AuthenticationServiceException("Unable to find an appropriate signature validator for ID Token."); |
467 | 460 | }
|
| 461 | + |
| 462 | +if (idToken instanceof PlainJWT) { |
| 463 | + |
| 464 | +if (clientAlg == null) { |
| 465 | +throw new AuthenticationServiceException("Unsigned ID tokens can only be used if explicitly configured in client."); |
| 466 | +} |
| 467 | + |
| 468 | +if (tokenAlg != null && !tokenAlg.equals(JWSAlgorithm.NONE)) { |
| 469 | +throw new AuthenticationServiceException("Unsigned token received, expected signature with " + tokenAlg); |
| 470 | +} |
| 471 | +} else if (idToken instanceof SignedJWT) { |
| 472 | + |
| 473 | +SignedJWT signedIdToken = (SignedJWT)idToken; |
| 474 | + |
| 475 | +if (tokenAlg.equals(JWSAlgorithm.HS256) |
| 476 | +|| tokenAlg.equals(JWSAlgorithm.HS384) |
| 477 | +|| tokenAlg.equals(JWSAlgorithm.HS512)) { |
| 478 | + |
| 479 | +// generate one based on client secret |
| 480 | +jwtValidator = symmetricCacheService.getSymmetricValidtor(clientConfig.getClient()); |
| 481 | +} else { |
| 482 | +// otherwise load from the server's public key |
| 483 | +jwtValidator = validationServices.getValidator(serverConfig.getJwksUri()); |
| 484 | +} |
| 485 | + |
| 486 | +if (jwtValidator != null) { |
| 487 | +if(!jwtValidator.validateSignature(signedIdToken)) { |
| 488 | +throw new AuthenticationServiceException("Signature validation failed"); |
| 489 | +} |
| 490 | +} else { |
| 491 | +logger.error("No validation service found. Skipping signature validation"); |
| 492 | +throw new AuthenticationServiceException("Unable to find an appropriate signature validator for ID Token."); |
| 493 | +} |
| 494 | +} // TODO: encrypted id tokens |
468 | 495 |
|
469 | 496 | // check the issuer
|
470 | 497 | if (idClaims.getIssuer() == null) {
|
|
0 commit comments