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
- Configure a signing credential on the RelyingPartyRegistration (signingX509Certificate/privateKey) so parameters resolve
- Inspect ex.getCause() from resolveSingle for credential evaluation failures
- Verify the credentials supplied to the resolver have USAGE_SIGNING and valid key material
- 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
- Configure signingX509Credentials on every RelyingPartyRegistration
- Fail fast at startup with a health check that performs a trial sign
- Ensure credentials are marked for signing usage in any custom resolver
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
- Saml2Exception wrapping exception while signing XMLObject
- Saml2Exception wrapping SecurityException while signing quer
- Saml2Exception wrapping DecryptionException during encrypted
- Saml2Exception wrapping exception while signing XMLObject
- relying_party_registration_not_found
AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10).
Data as JSON: /api/errors/025eea6ce798259e.
Report an issue: GitHub.