From 7ac1cd336d6f9717a2aa99a9483eb5a6c4865ecb Mon Sep 17 00:00:00 2001 From: Gustavo Valverde Date: Wed, 14 Oct 2026 10:26:36 +0100 Subject: [PATCH] refactor(sso): remove the ACS lookup that always returned undefined processSAMLResponse asked samlify for the POST ACS with the full binding URN, but samlify keys that lookup by short name, so it always returned undefined. The accepted Recipient values already include the providerId ACS route and every POST ACS declared in SP metadata. --- packages/sso/src/routes/saml-pipeline.ts | 14 -------------- packages/sso/src/saml/index.ts | 1 - packages/sso/src/saml/response-binding.ts | 3 +-- 3 files changed, 1 insertion(+), 17 deletions(-) diff --git a/packages/sso/src/routes/saml-pipeline.ts b/packages/sso/src/routes/saml-pipeline.ts index 63c5ef5ee1..3337245a3e 100644 --- a/packages/sso/src/routes/saml-pipeline.ts +++ b/packages/sso/src/routes/saml-pipeline.ts @@ -21,7 +21,6 @@ import { import { getSAMLPostAssertionConsumerServiceUrls, hasSAMLEncryptedAssertion, - SAML_HTTP_POST_BINDING, validateAudience, validateInResponseTo, validateSAMLAlgorithms, @@ -202,19 +201,11 @@ export function getSAMLRedirectCandidates( ]; } -function toArray(value: T | T[] | undefined): T[] { - if (Array.isArray(value)) { - return value; - } - return value ? [value] : []; -} - function getExpectedSAMLRecipients( config: SAMLConfig, baseURL: string, providerId: string, currentCallbackPath: string, - assertionConsumerServiceUrl: string | string[] | undefined, ): string[] { const configuredPostAssertionConsumerServiceUrls = getSAMLPostAssertionConsumerServiceUrls(config.spMetadata?.metadata); @@ -223,7 +214,6 @@ function getExpectedSAMLRecipients( currentCallbackPath, `${baseURL}/sso/saml2/sp/acs/${providerId}`, ...configuredPostAssertionConsumerServiceUrls, - ...toArray(assertionConsumerServiceUrl), ]; } @@ -432,15 +422,11 @@ export async function processSAMLResponse( sp.entityMeta.getEntityID(), parsedSamlConfig.audience, ]; - const assertionConsumerServiceUrl = sp.entityMeta.getAssertionConsumerService( - SAML_HTTP_POST_BINDING, - ); const expectedRecipients = getExpectedSAMLRecipients( parsedSamlConfig, ctx.context.baseURL, providerId, currentCallbackPath, - assertionConsumerServiceUrl, ); const serviceProviderPolicy = deriveSAMLServiceProviderPolicy(parsedSamlConfig); diff --git a/packages/sso/src/saml/index.ts b/packages/sso/src/saml/index.ts index 92ee2d236e..c983e05921 100644 --- a/packages/sso/src/saml/index.ts +++ b/packages/sso/src/saml/index.ts @@ -17,7 +17,6 @@ export { resolveSigningCerts, validateCertSources } from "./cert"; export { getSAMLPostAssertionConsumerServiceUrls, hasSAMLEncryptedAssertion, - SAML_HTTP_POST_BINDING, validateSAMLResponseBinding, } from "./response-binding"; export { validateAudience, validateInResponseTo } from "./response-validation"; diff --git a/packages/sso/src/saml/response-binding.ts b/packages/sso/src/saml/response-binding.ts index 94cdc07339..aa8f58e094 100644 --- a/packages/sso/src/saml/response-binding.ts +++ b/packages/sso/src/saml/response-binding.ts @@ -3,8 +3,7 @@ import { DOMParser } from "@xmldom/xmldom"; import { APIError } from "better-auth/api"; import { countAllNodes, xmlParser } from "./parser"; -export const SAML_HTTP_POST_BINDING = - "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"; +const SAML_HTTP_POST_BINDING = "urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"; const SAML_BEARER_CONFIRMATION_METHOD = "urn:oasis:names:tc:SAML:2.0:cm:bearer"; const SAML_METADATA_NAMESPACE = "urn:oasis:names:tc:SAML:2.0:metadata";