spring-projects/spring-security · error · Saml2Exception

Saml2Exception wrapping exception from signature signing…

Error message

Saml2Exception wrapping exception from signature signing parameters resolution (see also Assert: "Failed to resolve any signing credential")

What it means

This Saml2Exception wraps any failure that occurs while resolving SignatureSigningParameters, and is also thrown directly (as an assert) when the resolver returns null. The library throws it because it cannot produce a valid signing credential/algorithm configuration needed to sign SAML messages (auth requests, responses, metadata). Without signing parameters, outgoing SAML payloads cannot be secured.

Solutions

  1. Add at least one signing credential to the RelyingPartyRegistration: registration.signingX509Credentials(c -> c.add(signingCredential)).
  2. Verify the private key/certificate pair loads correctly (correct PEM format, no password mismatch) before building the registration.
  3. Check that a SignatureSigningParametersResolver is configured on the template/processor and that its criteria (algorithms, digest, canonicalization) are satisfiable.
  4. Inspect the wrapped cause (ex.getCause()) for the real resolver failure, e.g. KeyStore or PKCS issues.

Example fix

// before
RelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId("idp").build();
// after
RelyingPartyRegistration registration = RelyingPartyRegistration.withRegistrationId("idp")
    .signingX509Credentials(c -> c.add(new Saml2X509Credential(privateKey, certificate, Saml2X509CredentialType.SIGNING)))
    .build();
Defensive patterns

Strategy: validation

Validate before calling

if (registration.getSigningX509Credentials().isEmpty()) {
    throw new IllegalStateException("No signing credentials configured for " + registration.getRegistrationId());
}

Try / catch

try {
    SignatureSigningParameters p = template.resolveSigningParameters(context);
} catch (Saml2Exception ex) {
    logger.error("Signing credential resolution failed", ex.getCause());
}

Prevention

When it happens

Trigger: Calling OpenSaml5Template.resolveSigningParameters (via parameters(...)) when no SignatureSigningParametersResolver matches the criteria, or when the underlying resolver (e.g. DefaultSignatureSigningParametersResolver) throws while evaluating credentials.

Common situations: Relying party configured with no signing credentials in RelyingPartyRegistration (signingX509Credentials empty); private key cannot be read/decoded; signing algorithm/bignum config mismatch after upgrading to OpenSAML 5; metadata signing enabled without credentials.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/dd5385cb8083276f. Report an issue: GitHub.

Appendix: source

Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/metadata/OpenSaml5Template.java:302

		private SignatureSigningParameters resolveSigningParameters() {
			List<Credential> credentials = resolveSigningCredentials();
			List<String> digests = Collections.singletonList(SignatureConstants.ALGO_ID_DIGEST_SHA256);
			String canonicalization = SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;
			SignatureSigningParametersResolver resolver = new SAMLMetadataSignatureSigningParametersResolver();
			BasicSignatureSigningConfiguration signingConfiguration = new BasicSignatureSigningConfiguration();
			signingConfiguration.setSigningCredentials(credentials);
			signingConfiguration.setSignatureAlgorithms(this.algs);
			signingConfiguration.setSignatureReferenceDigestMethods(digests);
			signingConfiguration.setSignatureCanonicalizationAlgorithm(canonicalization);
			signingConfiguration.setKeyInfoGeneratorManager(buildSignatureKeyInfoGeneratorManager());
			CriteriaSet criteria = new CriteriaSet(new SignatureSigningConfigurationCriterion(signingConfiguration));
			try {
				SignatureSigningParameters parameters = resolver.resolveSingle(criteria);
				Assert.notNull(parameters, "Failed to resolve any signing credential");
				return parameters;
			}
			catch (Exception ex) {
				throw new Saml2Exception(ex);
			}
		}

		private NamedKeyInfoGeneratorManager buildSignatureKeyInfoGeneratorManager() {
			final NamedKeyInfoGeneratorManager namedManager = new NamedKeyInfoGeneratorManager();

			namedManager.setUseDefaultManager(true);
			final KeyInfoGeneratorManager defaultManager = namedManager.getDefaultManager();

			// Generator for X509Credentials
			final X509KeyInfoGeneratorFactory x509Factory = new X509KeyInfoGeneratorFactory();
			x509Factory.setEmitEntityCertificate(true);
			x509Factory.setEmitEntityCertificateChain(true);

			defaultManager.registerFactory(x509Factory);

			return namedManager;
		}

View on GitHub (pinned to 96852e8860)