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

  1. Ensure the wresult passed to buildAndVerifyAssertion is the complete, unmodified WS-Federation response token (decode/inspect it, no truncation or double-encoding).
  2. If the IdP encrypts tokens, configure the correct decryption keystore/private key in WsFederationConfiguration, or disable token encryption on the IdP relying-party trust.
  3. 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.
  4. 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

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


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)