From d964ea5cd18c8fb9ed7df9268b406b13fdba5b68 Mon Sep 17 00:00:00 2001 From: Javid Khan Date: Fri, 3 Jul 2026 23:59:59 +0530 Subject: [PATCH] match saml sso issuer exactly instead of by prefix --- .../saml/sso/SAMLSSOResponseValidator.java | 4 +-- .../sso/SAMLSSOResponseValidatorTest.java | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidator.java b/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidator.java index 85c0e0ede96..3b4e9c9fbce 100644 --- a/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidator.java +++ b/rt/rs/security/sso/saml/src/main/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidator.java @@ -169,8 +169,8 @@ private void validateIssuer(org.opensaml.saml.saml2.core.Issuer issuer) throws W return; } - // Issuer value must match (be contained in) Issuer IDP - if (enforceKnownIssuer && (issuer.getValue() == null || !issuerIDP.startsWith(issuer.getValue()))) { + // Issuer value must match the configured Issuer IDP + if (enforceKnownIssuer && !issuerIDP.equals(issuer.getValue())) { LOG.warning("Issuer value: " + issuer.getValue() + " does not match issuer IDP: " + issuerIDP); throw new WSSecurityException(WSSecurityException.ErrorCode.FAILURE, "invalidSAMLsecurity"); diff --git a/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidatorTest.java b/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidatorTest.java index 1bf6b656c03..4199a91bdcd 100644 --- a/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidatorTest.java +++ b/rt/rs/security/sso/saml/src/test/java/org/apache/cxf/rs/security/saml/sso/SAMLSSOResponseValidatorTest.java @@ -324,6 +324,34 @@ public void testResponseInvalidIssuer() throws Exception { } } + @org.junit.Test + public void testResponseIssuerPrefixOfConfiguredIssuer() throws Exception { + SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean(); + subjectConfirmationData.setAddress("http://apache.org"); + subjectConfirmationData.setInResponseTo("12345"); + subjectConfirmationData.setNotAfter(Instant.now().plus(Duration.ofMinutes(5))); + subjectConfirmationData.setRecipient("http://recipient.apache.org"); + + Response response = createResponse(subjectConfirmationData); + // A value that is merely a prefix of the configured issuer must not be accepted + response.setIssuer(SAML2PResponseComponentBuilder.createIssuer("http://cxf.apache.org")); + + // Validate the Response + SAMLSSOResponseValidator validator = new SAMLSSOResponseValidator(); + validator.setEnforceAssertionsSigned(false); + validator.setIssuerIDP("http://cxf.apache.org/issuer"); + validator.setAssertionConsumerURL("http://recipient.apache.org"); + validator.setClientAddress("http://apache.org"); + validator.setRequestId("12345"); + validator.setSpIdentifier("http://service.apache.org"); + try { + validator.validateSamlResponse(response, false); + fail("Expected failure on issuer that only matches a prefix of the configured issuer"); + } catch (WSSecurityException ex) { + // expected + } + } + @org.junit.Test public void testMissingAuthnStatement() throws Exception { SubjectConfirmationDataBean subjectConfirmationData = new SubjectConfirmationDataBean();