spring-projects/spring-security · error · Saml2Exception

Saml2Exception wrapping exception from signature signing par

Error message

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

What it means

resolveSigningParameters() uses an OpenSAML SignatureSigningParametersResolver; if resolution throws, the exception is wrapped in this Saml2Exception. A separate Assert fires with "Failed to resolve any signing credential" when no parameters resolve at all — both mean the template could not determine how to sign.

Source

Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/registration/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)

Solutions

  1. Configure a signing credential on the RelyingPartyRegistration (signingX509Certificate/privateKey) so parameters resolve
  2. Inspect ex.getCause() from resolveSingle for credential evaluation failures
  3. Verify the credentials supplied to the resolver have USAGE_SIGNING and valid key material
  4. Log the CriteriaSet used for resolution and confirm it matches how the resolver was configured

Example fix

// before
RelyingPartyRegistration reg = RelyingPartyRegistration.withRegistrationId("idp")
    .assertingPartyDetails(p -> p.singleSignOnServiceLocation("https://idp/sso"))
    .build(); // no signing credential
// after
RelyingPartyRegistration reg = RelyingPartyRegistration.withRegistrationId("idp")
    .signingX509Credentials(c -> c.add(new X509Certificate(certificate, privateKey)))
    .build();
Defensive patterns

Strategy: validation

Validate before calling

RelyingPartyRegistration reg = ...; // at startup
Assert.isTrue(!reg.getSigningX509Credentials().isEmpty(),
    "No signing credential configured for " + reg.getRegistrationId());

Try / catch

try {
    return template.sign(object);
} catch (Saml2Exception ex) {
    if (ex.getMessage() != null && ex.getMessage().contains("signing credential")) {
        throw new MisconfiguredSigningCredentialException(ex);
    }
    throw ex;
}

Prevention

When it happens

Trigger: Calling sign(...) when the resolver (e.g. BasicSignatureSigningParametersResolver configured with credentials) throws, or when no credential is configured so parameters is null and the Assert trips.

Common situations: No signing credential configured for the relying party (RelyingPartyRegistration without signing key); credential resolution criteria matching nothing (wrong entityID/usage); custom resolver throwing while evaluating credentials.

Related errors


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