{"record":{"id":"aea1993bf4b1c8ee","repo":"spring-projects/spring-security","slug":"unsupported-object-of-type-aea199","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/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/OpenSaml5Template.java#L374-L410","documentation":"OpenSaml5Template's internal verifier only supports verifying signatures on OpenSAML Assertion objects. If verify() is given any other signable XMLObject (e.g. a Response or LogoutRequest), it throws this Saml2Exception naming the object's class. Assertion verification additionally requires non-null ID, Issuer, and Signature.","triggerScenarios":"Calling verify(SignableXMLObject) with an object that is not an Assertion — e.g. a Response, ArtifactResolve, or custom SignableXMLObject implementation — so the instanceof Assertion branch falls through to the throw.","commonSituations":"Trying to verify a whole SAML Response's signature instead of the contained assertion; calling verify() on a LogoutRequest when processing SLO; passing an assertion whose signature was stripped during deserialization in other code paths.","solutions":["Extract the Assertion from the Response and pass the Assertion to verify() instead of the Response itself.","If response-level signature verification is needed, use OpenSAML's SignatureTrustEngine directly or rely on Spring Security's OpenSaml5AuthenticationProvider, which validates response/assertion signatures via validators.","For non-Assertion signable types, implement your own verification using a SignatureTrustEngine built from your credentials.","Ensure the object is an Assertion with non-null ID, Issuer, and Signature, or the earlier Assert checks will fail instead."],"exampleFix":"// before\nResponse response = ...;\ntemplate.verify(response); // unsupported type\n\n// after\nResponse response = ...;\nfor (Assertion assertion : response.getAssertions()) {\n    template.verify(assertion);\n}","handlingStrategy":"type-guard","validationCode":"if (!(signable instanceof Assertion a) || a.getID() == null || a.getIssuer() == null || a.getSignature() == null) {\n    throw new IllegalArgumentException(\"verify() requires an Assertion with ID, Issuer and Signature\");\n}","typeGuard":"boolean isVerifiableAssertion(SignableXMLObject o) {\n    return o instanceof Assertion a && a.getID() != null && a.getIssuer() != null && a.getSignature() != null;\n}","tryCatchPattern":"try { template.verify(signable); } catch (Saml2Exception ex) { log.error(\"Unsupported signable type: {}\", signable.getClass().getName()); throw ex; }","preventionTips":["Only pass objects matching instanceof Assertion to verify()","Extract assertions from Response before verification","Use the standard OpenSaml5AuthenticationProvider for full response/assertion validation"],"tags":["saml","opensaml","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"}