apereo/cas · error · IllegalArgumentException
Could not extract or decrypt an assertion based on the…
Error message
Could not extract or decrypt an assertion based on the security token provided
What it means
Thrown by WsFederationHelper.buildAndVerifyAssertion when the security token (wresult) could not be parsed into a usable SAML assertion. The token could not be extracted or decrypted, so validation ends before the issuer-configuration matching step that returns a Pair of assertion and configuration.
Solutions
- Ensure the wresult passed to buildAndVerifyAssertion is the complete, unmodified WS-Federation response token (decode/inspect it, no truncation or double-encoding).
- If the IdP encrypts tokens, configure the correct decryption keystore/private key in WsFederationConfiguration, or disable token encryption on the IdP relying-party trust.
- Verify the IdP is issuing a SAML 1.1/2.0 assertion format CAS supports for WS-Federation; adjust the IdP's claim rules/token format.
- Check the IdP did not return a fault/status response instead of a RequestedSecurityToken; inspect the raw wresult XML.
Example fix
// before: encrypted tokens, no decryption key configured
configuration.setKeystorePath(null);
// after: provide keystore with the token-decryption key
configuration.setKeystorePath("/etc/cas/keystore.jks");
configuration.setKeystorePassword("changeit");
configuration.setPrivateKeyPassword("changeit"); Defensive patterns
Strategy: validation
Validate before calling
// sanity-check the token before handing it to buildAndVerifyAssertion
if (securityToken == null || !securityToken.contains("RequestedSecurityToken")) {
throw new IllegalArgumentException("wresult does not contain a RequestedSecurityToken element");
} Type guard
function isUsableSecurityToken(wresult) {
return typeof wresult === 'string' && wresult.includes('RequestedSecurityToken') && wresult.includes('Assertion');
} Try / catch
try {
val pair = wsFederationHelper.buildAndVerifyAssertion(securityToken, configurations, service);
} catch (IllegalArgumentException e) {
LOGGER.error("Token could not be parsed/decrypted: {}", e.getMessage());
throw new BadWsFederationResponseException("unreadable-token");
} Prevention
- If the IdP encrypts tokens, provision the matching decryption keystore/private key in CAS before go-live.
- Log raw wresult (at debug) in a test environment and validate it parses as XML with an Assertion element.
- Confirm the IdP token format (SAML 1.1/2.0) matches what your CAS WS-Federation setup expects.
When it happens
Trigger: buildAndVerifyAssertion receives a wresult whose RequestedSecurityToken cannot be unmarshalled into an assertion: token XML is malformed, the token is encrypted and decryption keys (signing/encryption key material) are missing or wrong in WsFederationConfiguration, or an unexpected token type was returned.
Common situations: Copy-pasted or truncated wresult in tests/clients, IdP configured to encrypt tokens while CAS lacks the decryption keystore/key, XML namespace or version mismatch between IdP token format and CAS expectations, or CAS receiving an error/status token instead of an assertion.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- No groovy script cache manager is available to execute…
- Unable to determine the [WA] parameter
- The authentication request is not recognized
- Missing parameter wresult
- Could not validate assertion via the provided token
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/05a9c19af5249ff7.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-wsfederation/src/main/java/org/apereo/cas/support/wsfederation/WsFederationHelper.java:231
final Service service) {
val securityToken = getSecurityTokenFromRequestedToken(reqToken, config);
if (securityToken instanceof final Assertion assertion) {
LOGGER.debug("Extracted assertion successfully: [{}]", assertion);
val configuration = config.stream()
.filter(cfg -> StringUtils.isNotBlank(cfg.getIdentityProviderIdentifier()))
.filter(cfg -> {
val id = cfg.getIdentityProviderIdentifier();
LOGGER.trace("Comparing identity provider identifier [{}] with assertion issuer [{}]", id, assertion.getIssuer());
return RegexUtils.find(id, assertion.getIssuer());
})
.findFirst()
.orElseThrow(() ->
new IllegalArgumentException("Could not locate wsfed configuration for security token provided. The assertion issuer "
+ assertion.getIssuer() + " does not match any of the identity provider identifiers in the configuration"));
return Pair.of(assertion, configuration);
}
throw new IllegalArgumentException("Could not extract or decrypt an assertion based on the security token provided");
}
/**
* Gets assertion from security token.
*
* @param reqToken the req token
* @return the assertion from security token
*/
public XMLObject getAssertionFromSecurityToken(final RequestedSecurityToken reqToken) {
return reqToken.getSecurityTokens().getFirst();
}
/**
* validateSignature checks to see if the signature on an assertion is valid.
*
* @param resultPair a provided assertion
* @return true if the assertion's signature is valid, otherwise false
*/View on GitHub (pinned to e7288fc434)