Summary

The OpenID Connect core specification states, that the issuer in the ID Token must match the issuer in the issuer of the OIDC Provider.

But org.springframework.security.oauth2.client.oidc.authentication.OidcIdTokenValidator.validate(Jwt) does not validate the issuer. There is a TODO referencing a issue closed almost 3 years ago.

// 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

There is also no proper issuer field in the ClientRegistration. So it is not that easy to do the proper validation.

Actual Behavior

Issuer is not validated.

Expected Behavior

Issuer MUST be validated.

Version

spring security 5.2.2. Still in latest master.

Comment From: jgrandja

@furti Thank you for the reminder on this TODO. The iss validation should be pretty straight forward since the addition of ClientRegistrations.fromOidcIssuerLocation() in 5.1.

If the ClientRegistration is configured by the issuer-uri property, then ClientRegistration.providerDetails.configurationMetadata should contain the iss claim.

Would you be interested in submitting a PR for this?

Comment From: furti

Thanks for the quick reply. I will give it a try in the next couple of days. I have to check out the code at first and get it up and running :)

Comment From: furti

@jgrandja I have a question on the implementation details.

When validating the issuer URI, this will only work for Applications configured using the "issuer-uri" property you mentioned before.

But for all others using manual configuration (even CommonOAuth2Providers), this is a breaking change. Because this applications have no issuer in the ClientRegistration.providerDetails.configurationMetadata so the validation fails.

We should at least add a "ClientRegistration.Builder.issuer(String)" method, that makes it easy to manually set the issuer when using the builder directly.

Also the CommonOAuth2Providers should get the correct issuer set.

Comment From: jgrandja

@furti For the initial enhancement, let's validate if iss is available in ClientRegistration.providerDetails.configurationMetadata. If it's not available, because discovery wasn't used, then no validation takes place.

I logged a separate issue to consider adding ClientRegistration.providerDetails.issuerUri in #8326

Comment From: furti

@jgrandja I submitted a Pull Request for this issue. https://github.com/spring-projects/spring-security/pull/8357

Comment From: mengelbrecht

@jgrandja Will this be backported to the 5.3.x branch?

Comment From: jgrandja

@mengelbrecht This is an enhancement so it won't be backported to 5.3.x. This will only go into 5.4.x.

If you need this validation, you can provide a custom OAuth2TokenValidator and configure it via OidcIdTokenDecoderFactory.setJwtValidatorFactory().

NOTE: You also need to register the custom OidcIdTokenDecoderFactory as a @Bean. See the reference documentation for an example.