{"record":{"id":"0454a0f5a4a491e9","repo":"spring-projects/spring-security","slug":"unsupported-object-of-type-0454a0","errorCode":null,"errorMessage":"Unsupported object of type: ","messagePattern":"Unsupported object of type: ","errorType":"exception","errorClass":"Saml2Exception","httpStatus":null,"severity":"error","filePath":"saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/OpenSaml5Template.java","lineNumber":392,"sourceCode":"\t\t\tif (signable instanceof StatusResponseType response) {\n\t\t\t\tAssert.notNull(response.getID(), \"Response#ID cannot be null\");\n\t\t\t\tAssert.notNull(response.getIssuer(), \"Response#Issuer cannot be null\");\n\t\t\t\tAssert.notNull(response.getSignature(), \"Response#Signature cannot be null\");\n\t\t\t\treturn verifySignature(response.getID(), response.getIssuer(), response.getSignature());\n\t\t\t}\n\t\t\tif (signable instanceof RequestAbstractType request) {\n\t\t\t\tAssert.notNull(request.getID(), \"Request#ID cannot be null\");\n\t\t\t\tAssert.notNull(request.getIssuer(), \"Request#Issuer cannot be null\");\n\t\t\t\tAssert.notNull(request.getSignature(), \"Request#Signature cannot be null\");\n\t\t\t\treturn verifySignature(request.getID(), request.getIssuer(), request.getSignature());\n\t\t\t}\n\t\t\tif (signable instanceof Assertion assertion) {\n\t\t\t\tAssert.notNull(assertion.getID(), \"Assertion#ID cannot be null\");\n\t\t\t\tAssert.notNull(assertion.getIssuer(), \"Assertion#Issuer cannot be null\");\n\t\t\t\tAssert.notNull(assertion.getSignature(), \"Assertion#Signature cannot be null\");\n\t\t\t\treturn verifySignature(assertion.getID(), assertion.getIssuer(), assertion.getSignature());\n\t\t\t}\n\t\t\tthrow new Saml2Exception(\"Unsupported object of type: \" + signable.getClass().getName());\n\t\t}\n\n\t\tprivate Collection<Saml2Error> verifySignature(String id, Issuer issuer, Signature signature) {\n\t\t\tSignatureTrustEngine trustEngine = trustEngine(this.credentials);\n\t\t\tCriteriaSet criteria = verificationCriteria(issuer);\n\t\t\tCollection<Saml2Error> errors = new ArrayList<>();\n\t\t\tSAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();\n\t\t\ttry {\n\t\t\t\tprofileValidator.validate(signature);\n\t\t\t}\n\t\t\tcatch (Exception ex) {\n\t\t\t\terrors.add(new Saml2Error(Saml2ErrorCodes.INVALID_SIGNATURE,\n\t\t\t\t\t\t\"Invalid signature for object [\" + id + \"]: \"));\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tif (!trustEngine.validate(signature, criteria)) {\n\t\t\t\t\terrors.add(new Saml2Error(Saml2ErrorCodes.INVALID_SIGNATURE,","sourceCodeStart":374,"sourceCodeEnd":410,"githubUrl":"https://github.com/spring-projects/spring-security/blob/96852e8860138a482cb13d1479573f24ff6443c6/saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/web/authentication/logout/OpenSaml5Template.java#L374-L410","documentation":"Same family as error 583, in the logout OpenSaml5Template: its verify() method only handles Assertion instances; passing any other SignableXMLObject (such as a LogoutResponse) reaches the terminal throw of Saml2Exception naming the object's class.","triggerScenarios":"Calling logout OpenSaml5Template.verify(SignableXMLObject) with a non-Assertion object, so the instanceof Assertion check fails and the exception is thrown.","commonSituations":"Attempting to verify the signature of a LogoutResponse or LogoutRequest during single-logout processing; wrapping logic that forwards the whole SAML message to verify(); unit tests exercising verify() with mock signable objects.","solutions":["Verify signatures on the contained Assertion, or for logout messages use a SignatureTrustEngine (or Spring Security's Saml2LogoutValidator chain) that supports response-level signatures.","Build a SignatureTrustEngine from the SP credentials and verify the LogoutRequest/LogoutResponse signature yourself.","Use OpenSaml5AuthenticationProvider / Saml2LogoutValidator infrastructure which handles both response and assertion signature validation.","If the object should be an Assertion, check why a different type was passed (extraction logic bug) before calling verify()."],"exampleFix":"// before\nLogoutResponse resp = ...;\ntemplate.verify(resp); // unsupported\n\n// after\nLogoutResponse resp = ...;\nif (resp.getAssertions().size() > 0) {\n    template.verify(resp.getAssertions().get(0));\n} // or use SignatureTrustEngine for message-level signature","handlingStrategy":"type-guard","validationCode":"if (!(signable instanceof Assertion)) {\n    throw new IllegalArgumentException(\"logout template verify() supports Assertions only, got \" + signable.getClass().getName());\n}","typeGuard":"boolean isAssertion(SignableXMLObject o) { return o instanceof Assertion; }","tryCatchPattern":"try { template.verify(signable); } catch (Saml2Exception ex) { log.error(\"Unsupported type for logout verify(): {}\", signable.getClass().getName()); throw ex; }","preventionTips":["Verify assertions, not LogoutRequest/LogoutResponse envelopes","Use Saml2LogoutValidator or a SignatureTrustEngine for message-level signature checks","Route whole-message verification to Spring Security's standard SLO validation chain"],"tags":["saml","opensaml","logout","signature-verification","spring-security"],"backgroundTag":"unsupported-operation","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"}