fix: resolve SAML entity ID from metadata when external_key is null#3933
Merged
Conversation
Contributor
Author
|
We need to decide if we should ingest SAML metadata when bootstrapping SAML IDP providers from uaa.yml |
duanemay
previously approved these changes
Jun 5, 2026
…available. Fallback to previous behavior, continue startup, if metadata is not available. But log the error.
7a3006a to
e2be18c
Compare
duanemay
approved these changes
Jun 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
SAML login fails for IDPs bootstrapped from
uaa.ymlProblem
A SAML IDP configured in
uaa.ymlwith a URL-type metadata location (metadataTrustCheck: true+metaDataLocation: https://...) cannot authenticate users. Two distinct failure modes are observed depending on which ACS URL the IDP targets:Failure 1 —
relying_party_registration_not_found(primary reported symptom)When the IDP posts its SAML response to the IDP-alias ACS URL (
/saml/SSO/alias/{idpAlias}),UaaRelyingPartyRegistrationResolver.resolveFromRequestperforms anendsWithcheck against the SP entity-ID alias. Because the IDP alias does not end with the SP alias string, the resolver returnsnull, and Spring Security throws:Failure 2 —
invalid_issuer(secondary; same root cause)When the IDP posts to the canonical SP ACS URL (
/saml/SSO/alias/{spAlias}), the issuer is extracted from the SAML response and used to look up the IDP byexternal_key. Becauseexternal_keyisnullfor URL-type bootstrap IDPs (see root cause below), the lookup returns nothing. The default-stub registration is returned instead, and Spring Security throws:Root Cause
BootstrapSamlIdentityProviderData.setIdentityProvidersonly callsdef.setIdpEntityId(...)forDATA(inline XML) metadata type, never forURLtype.JdbcIdentityProviderProvisioningstoresexternal_key = saml.getIdpEntityId(), so all URL-type bootstrap IDPs are persisted withexternal_key = null. Both lookup paths that depend onexternal_keytherefore silently fail.Fix
1.
UaaRelyingPartyRegistrationResolver— fallback to URL alias as registration IDWhen
resolveFromRequestfinds that the URL path segment does not end with the SP alias but aSAMLResponseparameter is present, it now falls back to using the URL path segment (the IDP alias) directly as therelyingPartyRegistrationId.ConfiguratorRelyingPartyRegistrationRepositorycan then find the IDP by origin key.2.
ConfiguratorRelyingPartyRegistrationRepository— resolve entity ID from metadata whenexternal_keyis nullIn the loop that matches IDPs by entity ID, if
idpEntityId(sourced fromexternal_key) isnull, the repository now resolves the entity ID on-the-fly from the stored metadata viaSamlIdentityProviderConfigurator.getExtendedMetadataDelegate.Changes
server/.../saml/UaaRelyingPartyRegistrationResolver.java— fallback registration ID resolution from URL aliasserver/.../saml/ConfiguratorRelyingPartyRegistrationRepository.java— on-the-fly entity ID resolution from metadata whenexternal_keyis nullserver/.../saml/Saml2TestUtils.java— newresponseWithAssertions(issuer, pemKey, pemCert)overload for signing assertions with custom credentialsuaa/.../mock/saml/BootstrapSamlIdpSsoMockMvcTests.java— new regression test covering both failure modesTest Plan
BootstrapSamlIdpSsoMockMvcTests#samlResponse_viaIdpAliasUrl_authenticatesSuccessfully— reproducesrelying_party_registration_not_found; passes with fix inUaaRelyingPartyRegistrationResolverBootstrapSamlIdpSsoMockMvcTests#samlResponse_viaSpAliasUrl_authenticatesSuccessfully— reproducesinvalid_issuer; passes with fix inConfiguratorRelyingPartyRegistrationRepository./gradlew integrationTestto verify no regression in existing SAML flowsMade with Cursor