Validate ID Token Issuer
When the issuer is set in the provider metadata, we validate the iss field of the ID Token against it. The OpenID Connect Specification says this must always be validated. But this would be a breaking change for applications configured other than with ClientRegistrations.fromOidcIssuerLocation(issuer). This will be done later with #8326 Fixes gh-8321
This commit is contained in:
parent
70792a9072
commit
32ce94d2dd
|
@ -33,6 +33,7 @@ import java.time.Instant;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* An {@link OAuth2TokenValidator} responsible for
|
||||
|
@ -68,7 +69,12 @@ public final class OidcIdTokenValidator implements OAuth2TokenValidator<Jwt> {
|
|||
|
||||
// 2. The Issuer Identifier for the OpenID Provider (which is typically obtained during Discovery)
|
||||
// MUST exactly match the value of the iss (issuer) Claim.
|
||||
// TODO Depends on gh-4413
|
||||
String metadataIssuer = (String) this.clientRegistration.getProviderDetails().getConfigurationMetadata()
|
||||
.get("issuer");
|
||||
|
||||
if (metadataIssuer != null && !Objects.equals(metadataIssuer, idToken.getIssuer().toExternalForm())) {
|
||||
invalidClaims.put(IdTokenClaimNames.ISS, idToken.getIssuer());
|
||||
}
|
||||
|
||||
// 3. The Client MUST validate that the aud (audience) Claim contains its client_id value
|
||||
// registered at the Issuer identified by the iss (issuer) Claim as an audience.
|
||||
|
|
|
@ -92,6 +92,35 @@ public class OidcIdTokenValidatorTests {
|
|||
.allMatch(msg -> msg.contains(IdTokenClaimNames.ISS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateWhenMetadataIssuerMismatchThenHasErrors() {
|
||||
/*
|
||||
* When the issuer is set in the provider metadata, and it does not match the issuer in the ID Token,
|
||||
* the validation must fail
|
||||
*/
|
||||
Map<String, Object> configurationMetadata = new HashMap<>();
|
||||
configurationMetadata.put("issuer", "https://issuer.somethingelse.com");
|
||||
this.registration = this.registration.providerConfigurationMetadata(configurationMetadata);
|
||||
|
||||
assertThat(this.validateIdToken())
|
||||
.hasSize(1)
|
||||
.extracting(OAuth2Error::getDescription)
|
||||
.allMatch(msg -> msg.contains(IdTokenClaimNames.ISS));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateWhenMetadataIssuerMatchThenNoErrors() {
|
||||
/*
|
||||
* When the issuer is set in the provider metadata, and it does match the issuer in the ID Token,
|
||||
* the validation must succeed
|
||||
*/
|
||||
Map<String, Object> configurationMetadata = new HashMap<>();
|
||||
configurationMetadata.put("issuer", "https://issuer.example.com");
|
||||
this.registration = this.registration.providerConfigurationMetadata(configurationMetadata);
|
||||
|
||||
assertThat(this.validateIdToken()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void validateWhenSubNullThenHasErrors() {
|
||||
this.claims.remove(IdTokenClaimNames.SUB);
|
||||
|
|
Loading…
Reference in New Issue