{"record":{"id":"56889f43951bde8e","repo":"spring-projects/spring-security","slug":"saml2exception-wrapping-securityexception-while-si","errorCode":null,"errorMessage":"Saml2Exception wrapping SecurityException while signing query string (redirect binding)","messagePattern":"Saml2Exception wrapping SecurityException while signing query string \\(redirect binding\\)","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":279,"sourceCode":"\t\t\tCredential credential = parameters.getSigningCredential();\n\t\t\tAssert.notNull(credential, \"credential cannot be null when signing a SAML payload\");\n\t\t\tString algorithmUri = parameters.getSignatureAlgorithm();\n\t\t\tAssert.notNull(algorithmUri, \"algorithmUri cannot be null when signing a SAML payload\");\n\t\t\tthis.components.put(Saml2ParameterNames.SIG_ALG, algorithmUri);\n\t\t\tUriComponentsBuilder builder = UriComponentsBuilder.newInstance();\n\t\t\tfor (Map.Entry<String, String> component : this.components.entrySet()) {\n\t\t\t\tbuilder.queryParam(component.getKey(),\n\t\t\t\t\t\tUriUtils.encode(component.getValue(), StandardCharsets.ISO_8859_1));\n\t\t\t}\n\t\t\tString queryString = builder.build(true).toString().substring(1);\n\t\t\ttry {\n\t\t\t\tbyte[] rawSignature = XMLSigningUtil.signWithURI(credential, algorithmUri,\n\t\t\t\t\t\tqueryString.getBytes(StandardCharsets.UTF_8));\n\t\t\t\tString b64Signature = Saml2Utils.samlEncode(rawSignature);\n\t\t\t\tthis.components.put(Saml2ParameterNames.SIGNATURE, b64Signature);\n\t\t\t}\n\t\t\tcatch (SecurityException ex) {\n\t\t\t\tthrow new Saml2Exception(ex);\n\t\t\t}\n\t\t\treturn this.components;\n\t\t}\n\n\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);","sourceCodeStart":261,"sourceCodeEnd":297,"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#L261-L297","documentation":"The redirect-binding sign(Map) variant signs the raw query string with XMLSigningUtil.signWithURI using the resolved signing credential; OpenSAML SecurityException from that operation is wrapped in this Saml2Exception. It means the HTTP-Redirect signature computation failed, almost always due to a credential/key problem.","triggerScenarios":"Building a signed redirect-binding URL (e.g. SAML logout/AuthnRequest redirects) when the credential cannot produce an RSA/EC signature: credential has no private key, key algorithm doesn't match the resolved signatureAlgorithmUri, or crypto provider rejects the operation.","commonSituations":"Delegated logout redirects with a certificate that lacks the private key; mismatch between configured signing algorithm (e.g. ECDSA) and an RSA key; HSM/PKCS11 provider unavailable so key access fails at sign time.","solutions":["Check ex.getCause() for the underlying SecurityException detail (key type, algorithm, provider)","Ensure the signing credential includes a usable private key matching the configured signature algorithm (RSA key with RSA-SHA256, EC key with ECDSA-SHA256, etc.)","Verify the keystore/HSM is accessible at runtime and the key password is correct","Log the resolved SignatureSigningParameters (algorithm + credential type) to confirm a coherent combination"],"exampleFix":"// before\n.sign(\"http://www.w3.org/2001/04/xmldsig-more#ecdsa-sha256\") // EC algorithm with RSA key\n// after\n.sign(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); // match algorithm to the RSA private key","handlingStrategy":"try-catch","validationCode":"Assert.notNull(privateKey, \"Redirect binding signing requires a private key\");\n// key/algorithm compatibility\nAssert.isTrue(rsaKey || ecKeyMatchesAlgorithm, \"Signature algorithm does not match key type\");","typeGuard":null,"tryCatchPattern":"try {\n    Map<String, String> params = template.sign(queryParams);\n} catch (Saml2Exception ex) {\n    logger.error(\"Redirect-binding signing failed: \" + ex.getCause(), ex);\n    throw ex;\n}","preventionTips":["Confirm the HSM/keystore provider is available in the runtime environment","Use algorithm URIs consistent with the credential key type","Log resolved SignatureSigningParameters during troubleshooting"],"tags":["saml2","opensaml","signing","redirect-binding","credential"],"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"}