Skip to content

#37085 include in 25.07.10 LTS — backport SAML NameID serialization API - #37089

Open
fabrizzio-dotCMS wants to merge 1 commit into
release-25.07.10_ltsfrom
issue-37085-samlnameid-lts
Open

#37085 include in 25.07.10 LTS — backport SAML NameID serialization API#37089
fabrizzio-dotCMS wants to merge 1 commit into
release-25.07.10_ltsfrom
issue-37085-samlnameid-lts

Conversation

@fabrizzio-dotCMS

Copy link
Copy Markdown
Member

Proposed Changes

Backport of the SAML NameID serialization API from #34700 (PR #35122) to the 25.07.10 LTS line. This is the enabling step for #37085: it lets the LTS line run the Maven-built SAML bundle that carries BouncyCastle 1.85.

  • Add com.dotcms.saml.SamlNameID — a serializable, OpenSAML-free holder for a NameID's XML string. It has to live on the webapp classpath so Tomcat's session deserializer can resolve it; plugin bundle classes are invisible to that classloader. File is byte-identical to main.
  • Narrow Attributes.nameID (field, getter, and both builder members) from Object to Serializable.
  • Update SAMLHelperTest to build NameIDs through the new type.
  • Add entry 47 to hotfix_tracking.md.

Why the Attributes change is required, not cosmetic

Shipping SamlNameID alone would still fail at runtime. The SAML bundle is compiled against the newer core, so its bytecode references:

com/dotcms/saml/Attributes.getNameID:()Ljava/io/Serializable;
com/dotcms/saml/Attributes$Builder.nameID:(Ljava/io/Serializable;)Lcom/dotcms/saml/Attributes$Builder;

The LTS core declares both as Object, so the bundle would throw NoSuchMethodError on the SAML authentication path. Compiling the bundle's source against the LTS jar does not surface this — only the shipped descriptors do.

Verification

  • Scanned all 105 dotCMS-owned members the built bundle references in its bytecode against dotcms-core-25.07.10_lts_v17. Three real gaps: the SamlNameID class and the two descriptors above. One false positive, WebInterceptorDelegate.addFirst, which is inherited from WebInterceptorAware and is present in LTS with the exact descriptor.
  • Patched a copy of the LTS core jar with the backported classes and re-ran the scan: zero unresolved references.
  • javac --release 11 clean on both changed classes — no Java 11 target violations.
  • All eight nameID call sites in SAMLHelper and DotSamlResource pass the value into Object-typed parameters or back into the builder; none break under the narrowing. SAMLHelper.java is byte-identical between this branch and main, so main's green build covers those call sites.
  • No production code calls .toString() on the NameID — worth stating explicitly because SamlNameID.toString() is redacted, and hashing that redacted string would collide every SAML user onto one ID.

Checklist

  • Tests — SAMLHelperTest updated and carried over from fix: serialize SAML NameID for Redis session storage #34700 #35122
  • Translations — n/a
  • Security Implications Contemplated — SamlNameID carries PII (the SAML identity value). Its toString() is redacted and readObject enforces non-blank plus length caps so a corrupt or hostile Redis session entry cannot exhaust heap. Behavior is unchanged from what already ships on main.

Additional Info

Not yet covered by any of the above: a real SAML login + logout smoke test on an LTS image. That is a QA step.

This PR does not bump com.dotcms.samlbundle in osgi-base/system-bundles/pom.xml. That happens once the LTS-targeted bundle version is published and its number is agreed with release.

Related to #37085.

Backport the SAML NameID serialization API from #34700 (PR #35122) so the LTS line
can run the Maven-built SAML bundle that carries BouncyCastle 1.85.

- Add com.dotcms.saml.SamlNameID: a serializable, OpenSAML-free holder for a NameID's
  XML string. It must live on the webapp classpath so Tomcat's session deserializer
  can resolve it; plugin bundle classes are invisible to that classloader.
- Narrow Attributes.nameID (field, getter and builder) from Object to Serializable.
  This is not cosmetic: the bundle's bytecode references
  Attributes.getNameID()Ljava/io/Serializable; and
  Attributes$Builder.nameID(Ljava/io/Serializable;), so shipping SamlNameID alone
  would still fail with NoSuchMethodError on the SAML authentication path.
- Update SAMLHelperTest to build NameIDs through the new type.

No production code in core reads the narrowed members with an incompatible type:
all eight call sites in SAMLHelper and DotSamlResource pass the value into Object-typed
parameters or back into the builder. SAMLHelper is byte-identical to main.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

2 participants