Fix: SAML metadata ACS URL ignores zone subdomain when entityBaseURL is set#3915
Open
fhanik wants to merge 2 commits into
Open
Fix: SAML metadata ACS URL ignores zone subdomain when entityBaseURL is set#3915fhanik wants to merge 2 commits into
fhanik wants to merge 2 commits into
Conversation
…s (regression from #3739)
Contributor
Author
|
@georgikpetrov00 - can you review? |
Member
|
I think we should add a section to UAA-Configuration-Reference.md that has a summary of the table from the initial comment for how entityBaseURL works in different scenarios. |
Expanded `entityBaseURL` documentation to detail behavior across different zone access patterns, added examples, and explained implications for path-based zone access with SAML metadata generation.
georgikpetrov00
approved these changes
May 16, 2026
Contributor
georgikpetrov00
left a comment
There was a problem hiding this comment.
My only thoughts are on the 2 comments mentioned. Everything else looks great.
Comment on lines
+181
to
+183
| // Path-based zone: ZonePathContextRewritingFilter has embedded /z/{subdomain} | ||
| // into the context path. entityBaseURL is a static value that cannot reflect this | ||
| // dynamically, so always derive from the request for this access pattern. |
Contributor
There was a problem hiding this comment.
Suggestion: This is already explained in the javadoc above and can be deleted.
Comment on lines
+192
to
+193
| // Subdomain-based zone with entityBaseURL configured: prepend the zone | ||
| // subdomain to the host so ACS/SLO endpoints resolve to the right virtual host. |
strehle
approved these changes
May 19, 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.
Fix: SAML metadata ACS URL ignores zone subdomain when
entityBaseURLis setBackground — the regression introduced by #3739
PR #3739 ("Use entityBaseURL for URLs when generating SAML Metadata", merged 2026-02-19, commit
4123092) changedUaaRelyingPartyRegistrationResolverto use the operator-configuredlogin.entityBaseURLas the base for all SAML SP metadata URLs.The intent was correct — a static, canonical base URL produces stable metadata behind proxies and load balancers. However, the implementation applied
entityBaseURLverbatim for all zones, including non-default identity zones accessed via subdomain (e.g.testzone-jnakrm.localhost). BecauseentityBaseURLis a single static value (http://localhost:8080/uaa), the generated metadata for any non-default zone contained the wrong host:The correct URL for a subdomain-based zone is:
Why the existing test did not catch this
SamlMetadataEndpointMockMvcTests#nonDefaultZoneSamlMetadataXMLValidation— the test that directly exercises non-default zone metadata — only asserted withcontainsStringon the path suffix:The path suffix was correct (
/saml/SSO/alias/testzone-jnakrm.integration-saml-entity-id); only the host was wrong (localhostvstestzone-jnakrm.localhost). Because the assertion never checked the full URL, the test kept passing throughout the regression.What this PR fixes
UaaRelyingPartyRegistrationResolver— addsresolveBaseUrlwhich selects the correct base URL for each access pattern:entityBaseURLnot setHttpServletRequestentityBaseURLsetentityBaseURLas-isentityBaseURLsetentityBaseURLhost viaUaaUrlUtils.addSubdomainToUrl/z/{subdomain}/), anyentityBaseURLentityBaseURLis a static value that cannot encode the dynamic zone path;ZonePathContextRewritingFilterhas already embedded the zone in the context pathSamlMetadataEndpointMockMvcTests— three improvements:containsStringtoequalTowith the full expected URL, so no future host regression can go undetected.nonDefaultZoneSamlMetadataXMLValidationnow asserts the full ACS Location URL (scheme + host + path), not just the path suffix.SamlMetadataZonePathMockMvcTestsnested class covers identity zones accessed via path (/z/{subdomain}/). It is placed in a@Nested @TestPropertySource(properties = {"zones.paths.enabled=true"})class — the same pattern the other config-variant nested classes use — so the test always runs unconditionally without relying on a Gradle system-property default.UaaRelyingPartyRegistrationResolverTests— adds two unconditional unit tests (no@EnabledIfZonePathsEnabledgate) coveringresolveBaseUrlfor both zone access patterns:resolveWhenEntityBaseUrlIsSetAndNonDefaultZonePathIgnoresEntityBaseUrlAndUsesRequestContextPath— usesZONE_ORIGINAL_CONTEXT_PATH = ""andcontextPath = "/z/myzone", which is the realistic value the filter sets in a no-servlet-context-path environment (MockMvc / embedded server). This test is the unconditional safety net: it fails immediately ifisZonePathRequestis broken or removed, regardless of whetherzones.paths.enabledis set as a system property.resolveWhenEntityBaseUrlIsSetAndNonDefaultZonePathWithServletContextPathIgnoresEntityBaseUrl— covers the production deployment variant (contextPath = "/uaa/z/myzone",ZONE_ORIGINAL_CONTEXT_PATH = "/uaa").SamlMetadataEndpointKeyRotationTests— fixes a bug introduced by #3739 in the test itself: the resolver was constructed withentityBaseURL = "http://zone-id.localhost:8080/uaa"— the zone-specific URL with the subdomain already baked in. BecauseresolveBaseUrlnow correctly prepends the zone subdomain, this produced a doubled subdomain (http://zone-id.zone-id.localhost:8080/uaa). The test is corrected to use"http://localhost:8080/uaa"— the UAA instance base URL, consistent with what operators configure inlogin.entityBaseURLand whatintegration_test_properties.ymlcontains.