{"record":{"id":"05a9c19af5249ff7","repo":"apereo/cas","slug":"could-not-extract-or-decrypt-an-assertion-based-on","errorCode":null,"errorMessage":"Could not extract or decrypt an assertion based on the security token provided","messagePattern":"Could not extract or decrypt an assertion based on the security token provided","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"support/cas-server-support-wsfederation/src/main/java/org/apereo/cas/support/wsfederation/WsFederationHelper.java","lineNumber":231,"sourceCode":"                                                                              final Service service) {\n        val securityToken = getSecurityTokenFromRequestedToken(reqToken, config);\n        if (securityToken instanceof final Assertion assertion) {\n            LOGGER.debug(\"Extracted assertion successfully: [{}]\", assertion);\n            val configuration = config.stream()\n                .filter(cfg -> StringUtils.isNotBlank(cfg.getIdentityProviderIdentifier()))\n                .filter(cfg -> {\n                    val id = cfg.getIdentityProviderIdentifier();\n                    LOGGER.trace(\"Comparing identity provider identifier [{}] with assertion issuer [{}]\", id, assertion.getIssuer());\n                    return RegexUtils.find(id, assertion.getIssuer());\n                })\n                .findFirst()\n                .orElseThrow(() ->\n                    new IllegalArgumentException(\"Could not locate wsfed configuration for security token provided. The assertion issuer \"\n                                                 + assertion.getIssuer() + \" does not match any of the identity provider identifiers in the configuration\"));\n\n            return Pair.of(assertion, configuration);\n        }\n        throw new IllegalArgumentException(\"Could not extract or decrypt an assertion based on the security token provided\");\n    }\n\n    /**\n     * Gets assertion from security token.\n     *\n     * @param reqToken the req token\n     * @return the assertion from security token\n     */\n    public XMLObject getAssertionFromSecurityToken(final RequestedSecurityToken reqToken) {\n        return reqToken.getSecurityTokens().getFirst();\n    }\n\n    /**\n     * validateSignature checks to see if the signature on an assertion is valid.\n     *\n     * @param resultPair a provided assertion\n     * @return true if the assertion's signature is valid, otherwise false\n     */","sourceCodeStart":213,"sourceCodeEnd":249,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-wsfederation/src/main/java/org/apereo/cas/support/wsfederation/WsFederationHelper.java#L213-L249","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: encrypted tokens, no decryption key configured\nconfiguration.setKeystorePath(null);\n// after: provide keystore with the token-decryption key\nconfiguration.setKeystorePath(\"/etc/cas/keystore.jks\");\nconfiguration.setKeystorePassword(\"changeit\");\nconfiguration.setPrivateKeyPassword(\"changeit\");","handlingStrategy":"validation","validationCode":"// sanity-check the token before handing it to buildAndVerifyAssertion\nif (securityToken == null || !securityToken.contains(\"RequestedSecurityToken\")) {\n    throw new IllegalArgumentException(\"wresult does not contain a RequestedSecurityToken element\");\n}","typeGuard":"function isUsableSecurityToken(wresult) {\n  return typeof wresult === 'string' && wresult.includes('RequestedSecurityToken') && wresult.includes('Assertion');\n}","tryCatchPattern":"try {\n    val pair = wsFederationHelper.buildAndVerifyAssertion(securityToken, configurations, service);\n} catch (IllegalArgumentException e) {\n    LOGGER.error(\"Token could not be parsed/decrypted: {}\", e.getMessage());\n    throw new BadWsFederationResponseException(\"unreadable-token\");\n}","preventionTips":["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."],"tags":["ws-federation","assertion-extraction","token-decryption","malformed-token"],"backgroundTag":"invalid-argument-format","analyzedSha":"e7288fc434b4f4505b8452e1a57e8fb3111bb863","analyzedAt":"2026-09-08T15:39:16.015Z","contentChangedAt":"2026-09-08T15:39:16.015Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}