{"record":{"id":"025eea6ce798259e","repo":"spring-projects/spring-security","slug":"saml2exception-wrapping-exception-from-signature-s-025eea","errorCode":null,"errorMessage":"Saml2Exception wrapping exception from signature signing parameters resolution (see also Assert: \"Failed to resolve any signing credential\")","messagePattern":"Saml2Exception wrapping exception from signature signing parameters resolution \\(see also Assert: \"Failed to resolve any signing credential\"\\)","errorType":"exception","errorClass":"Saml2Exception","httpStatus":null,"severity":"error","filePath":"saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/registration/OpenSaml5Template.java","lineNumber":302,"sourceCode":"\t\tprivate SignatureSigningParameters resolveSigningParameters() {\n\t\t\tList<Credential> credentials = resolveSigningCredentials();\n\t\t\tList<String> digests = Collections.singletonList(SignatureConstants.ALGO_ID_DIGEST_SHA256);\n\t\t\tString canonicalization = SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS;\n\t\t\tSignatureSigningParametersResolver resolver = new SAMLMetadataSignatureSigningParametersResolver();\n\t\t\tBasicSignatureSigningConfiguration signingConfiguration = new BasicSignatureSigningConfiguration();\n\t\t\tsigningConfiguration.setSigningCredentials(credentials);\n\t\t\tsigningConfiguration.setSignatureAlgorithms(this.algs);\n\t\t\tsigningConfiguration.setSignatureReferenceDigestMethods(digests);\n\t\t\tsigningConfiguration.setSignatureCanonicalizationAlgorithm(canonicalization);\n\t\t\tsigningConfiguration.setKeyInfoGeneratorManager(buildSignatureKeyInfoGeneratorManager());\n\t\t\tCriteriaSet criteria = new CriteriaSet(new SignatureSigningConfigurationCriterion(signingConfiguration));\n\t\t\ttry {\n\t\t\t\tSignatureSigningParameters parameters = resolver.resolveSingle(criteria);\n\t\t\t\tAssert.notNull(parameters, \"Failed to resolve any signing credential\");\n\t\t\t\treturn parameters;\n\t\t\t}\n\t\t\tcatch (Exception ex) {\n\t\t\t\tthrow new Saml2Exception(ex);\n\t\t\t}\n\t\t}\n\n\t\tprivate NamedKeyInfoGeneratorManager buildSignatureKeyInfoGeneratorManager() {\n\t\t\tfinal NamedKeyInfoGeneratorManager namedManager = new NamedKeyInfoGeneratorManager();\n\n\t\t\tnamedManager.setUseDefaultManager(true);\n\t\t\tfinal KeyInfoGeneratorManager defaultManager = namedManager.getDefaultManager();\n\n\t\t\t// Generator for X509Credentials\n\t\t\tfinal X509KeyInfoGeneratorFactory x509Factory = new X509KeyInfoGeneratorFactory();\n\t\t\tx509Factory.setEmitEntityCertificate(true);\n\t\t\tx509Factory.setEmitEntityCertificateChain(true);\n\n\t\t\tdefaultManager.registerFactory(x509Factory);\n\n\t\t\treturn namedManager;\n\t\t}","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/registration/OpenSaml5Template.java#L284-L320","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nRelyingPartyRegistration reg = RelyingPartyRegistration.withRegistrationId(\"idp\")\n    .assertingPartyDetails(p -> p.singleSignOnServiceLocation(\"https://idp/sso\"))\n    .build(); // no signing credential\n// after\nRelyingPartyRegistration reg = RelyingPartyRegistration.withRegistrationId(\"idp\")\n    .signingX509Credentials(c -> c.add(new X509Certificate(certificate, privateKey)))\n    .build();","handlingStrategy":"validation","validationCode":"RelyingPartyRegistration reg = ...; // at startup\nAssert.isTrue(!reg.getSigningX509Credentials().isEmpty(),\n    \"No signing credential configured for \" + reg.getRegistrationId());","typeGuard":null,"tryCatchPattern":"try {\n    return template.sign(object);\n} catch (Saml2Exception ex) {\n    if (ex.getMessage() != null && ex.getMessage().contains(\"signing credential\")) {\n        throw new MisconfiguredSigningCredentialException(ex);\n    }\n    throw ex;\n}","preventionTips":["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"],"tags":["saml2","opensaml","signing","credential","configuration"],"backgroundTag":"missing-credentials","analyzedSha":"96852e8860138a482cb13d1479573f24ff6443c6","analyzedAt":"2026-09-10T23:25:23.477Z","contentChangedAt":"2026-09-10T23:25:23.477Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}