spring-projects/spring-security · error · Saml2Exception

Unsupported object of type:

Error message

Unsupported object of type: 

What it means

OpenSaml5Template.verify() only supports verifying signatures on SAML objects of known types (e.g. Assertion, Response, EncryptedAssertion). If a SignableXMLObject of another type is passed, it throws Saml2Exception('Unsupported object of type: ' + className). This guards against silently accepting objects whose signature verification semantics are not implemented.

Source

Thrown at saml2/saml2-service-provider/src/opensaml5Main/java/org/springframework/security/saml2/provider/service/web/OpenSaml5Template.java:392

			if (signable instanceof StatusResponseType response) {
				Assert.notNull(response.getID(), "Response#ID cannot be null");
				Assert.notNull(response.getIssuer(), "Response#Issuer cannot be null");
				Assert.notNull(response.getSignature(), "Response#Signature cannot be null");
				return verifySignature(response.getID(), response.getIssuer(), response.getSignature());
			}
			if (signable instanceof RequestAbstractType request) {
				Assert.notNull(request.getID(), "Request#ID cannot be null");
				Assert.notNull(request.getIssuer(), "Request#Issuer cannot be null");
				Assert.notNull(request.getSignature(), "Request#Signature cannot be null");
				return verifySignature(request.getID(), request.getIssuer(), request.getSignature());
			}
			if (signable instanceof Assertion assertion) {
				Assert.notNull(assertion.getID(), "Assertion#ID cannot be null");
				Assert.notNull(assertion.getIssuer(), "Assertion#Issuer cannot be null");
				Assert.notNull(assertion.getSignature(), "Assertion#Signature cannot be null");
				return verifySignature(assertion.getID(), assertion.getIssuer(), assertion.getSignature());
			}
			throw new Saml2Exception("Unsupported object of type: " + signable.getClass().getName());
		}

		private Collection<Saml2Error> verifySignature(String id, Issuer issuer, Signature signature) {
			SignatureTrustEngine trustEngine = trustEngine(this.credentials);
			CriteriaSet criteria = verificationCriteria(issuer);
			Collection<Saml2Error> errors = new ArrayList<>();
			SAMLSignatureProfileValidator profileValidator = new SAMLSignatureProfileValidator();
			try {
				profileValidator.validate(signature);
			}
			catch (Exception ex) {
				errors.add(new Saml2Error(Saml2ErrorCodes.INVALID_SIGNATURE,
						"Invalid signature for object [" + id + "]: "));
			}

			try {
				if (!trustEngine.validate(signature, criteria)) {
					errors.add(new Saml2Error(Saml2ErrorCodes.INVALID_SIGNATURE,

View on GitHub (pinned to 96852e8860)

Solutions

  1. Only pass Assertion/Response (supported signables) to verify()
  2. Verify the enclosing Response/Assertion in OpenSamlAuthenticationProvider instead of ad-hoc elements
  3. Extend the verify method (subclass or upstream contribution) if you genuinely need another signable type
  4. Log signable.getClass().getName() to identify which object leaked in

Example fix

// before
template.verify(subjectConfirmationData);
// after
template.verify(assertion); // verify at the supported container level
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(signable instanceof Assertion) && !(signable instanceof Response)) throw new IllegalArgumentException("verify() supports only Assertion/Response");

Type guard

function isVerifiable(o) { return o instanceof Assertion || o instanceof Response; }

Try / catch

try { errors = template.verify(obj); } catch (Saml2Exception e) { throw new UnsupportedOperationException("Verify unsupported for " + obj.getClass(), e); }

Prevention

When it happens

Trigger: Invoking the public verify(SignableXMLObject) with a signable object that is not an Assertion (or the other supported types), e.g. a raw Response, SubjectConfirmationData, ArtifactResolve, or a custom OpenSAML element.

Common situations: Custom SAML processing code calling the template's verification method directly with an unsupported element; library version differences where a new SAML element is routed to verify; refactoring that changed which object is passed to verification.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of spring-projects/spring-security@96852e8860 (2026-09-10). Data as JSON: /api/errors/cdacbe350f461238. Report an issue: GitHub.