Skip to content

OidcIdTokenDecoderFactory caching of ClientRegistration fails to decode tokens if clientId changes #12816

@unb

Description

@unb

Describe the bug
OidcIdTokenDecoderFactory caches JwtDecoder instances on ClientRegistration.getRegistrationId(). The cached instance holds a reference to the ClientRegistration. If a new ClientRegistration is created with a different clientId but the same registrationId, the cached JwtDecoder is still returned. This causes validation errors when parsing tokens: "[invalid_id_token] The ID Token contains invalid claims..."

	public JwtDecoder createDecoder(ClientRegistration clientRegistration) {
		Assert.notNull(clientRegistration, "clientRegistration cannot be null");
		return this.jwtDecoders.computeIfAbsent(clientRegistration.getRegistrationId(), (key) -> {
			NimbusJwtDecoder jwtDecoder = buildDecoder(clientRegistration);
			jwtDecoder.setJwtValidator(this.jwtValidatorFactory.apply(clientRegistration));
			Converter<Map<String, Object>, Map<String, Object>> claimTypeConverter = this.claimTypeConverterFactory
					.apply(clientRegistration);
			if (claimTypeConverter != null) {
				jwtDecoder.setClaimSetConverter(claimTypeConverter);
			}
			return jwtDecoder;
		});
	}

To Reproduce

ClientRegistration registration1 = CommonOAuth2Provider.GOOGLE.getBuilder("google").clientId("1").....build();
ClientRegistration registration2 = CommonOAuth2Provider.GOOGLE.getBuilder("google").clientId("2").....build();

OidcIdTokenDecoderFactory factory = new OidcIdTokenDecoderFactory();
JwtDecoder decoder1 = factory.createDecoder(registration1);
Jwt jwt1 = decoder1.decode(token1);  // token1 associated with clientId "1"
JwtDecoder decoder2 = factory.createDecoder(registration2);
Jwt jwt2 = decoder2.decode(token2);  // token2 associated with clientId "2". 

// The second call to decode() fails with "[invalid_id_token] The ID Token contains invalid claims..." as decoder2 == decoder1, which points to registration1 

**Expected behavior**
The OidcIdTokenDecoderFactory should discard the cached instance if the cached ClientRegistration has a different clientId to that supplied.

Metadata

Metadata

Assignees

No one assigned

    Labels

    in: oauth2An issue in OAuth2 modules (oauth2-core, oauth2-client, oauth2-resource-server, oauth2-jose)type: bugA general bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions