apereo/cas · error · IllegalArgumentException

Could not validate assertion via the provided token

Error message

Could not validate assertion via the provided token

What it means

After extracting wresult, the validator calls wsFederationHelper.buildAndVerifyAssertion to parse and verify the RequestSecurityToken into a SAML assertion. If the helper returns null (token unparseable or verification failed), it throws IllegalArgumentException stating the assertion could not be validated from the provided token.

Solutions

  1. Verify the WS-Fed service registration in CAS holds the current IdP signing certificate and correct entity/realm IDs.
  2. Enable debug logging on WsFederationHelper and WsFederationResponseValidator to see why the assertion failed to build/verify (parse error vs signature).
  3. Re-test with a freshly minted sign-in response to rule out expired/replayed or truncated token payloads.
  4. Synchronize clocks (NTP) on IdP and CAS to eliminate time-based assertion validation failures.

Example fix

// before: stale certificate in CAS service registration
"signingCertificate": "MIIB...OLD-EXPIRED-CERT...",
// after: current IdP signing certificate
"signingCertificate": "MIIB...CURRENT-IDP-CERT..."
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-check that the token is well-formed XML before handing it off:
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.newDocumentBuilder().parse(new InputSource(new StringReader(wresult)));

Try / catch

try {
    validator.validateWsFederationAuthenticationRequest(context);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("Could not validate assertion")) {
        // refresh IdP signing cert / check service trust config, then re-authenticate
        throw new AuthenticationException("WS-Fed assertion rejected", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: buildAndVerifyAssertion(rsToken, configurations, service) returns null for the wresult token — malformed token XML, unsigned or improperly signed token, or service configuration (signing cert / entity id) that does not verify the assertion.

Common situations: IdP signing certificate rotated or changed without updating the WS-Fed service registration in CAS; clock skew making the assertion invalid; wrong relying-party trust configuration (mismatched entity ID or certificate) so signature verification silently fails; truncated wresult due to URL-encoding or proxy mangling.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08). Data as JSON: /api/errors/7e37a408fdacdb55. Report an issue: GitHub.

Appendix: source

Thrown at support/cas-server-support-wsfederation-webflow/src/main/java/org/apereo/cas/web/flow/WsFederationResponseValidator.java:65

     * @throws Throwable the throwable
     */
    public void validateWsFederationAuthenticationRequest(final RequestContext context) throws Throwable {
        val service = wsFederationCookieManager.retrieve(context);
        LOGGER.debug("Retrieved service [{}] from the session cookie", service);

        val request = WebUtils.getHttpServletRequestFromExternalWebflowContext(context);
        val wResult = request.getParameter(WRESULT);
        LOGGER.debug("Parameter [{}] received: [{}]", WRESULT, wResult);
        if (StringUtils.isBlank(wResult)) {
            LOGGER.error("No [{}] parameter is found", WRESULT);
            throw new IllegalArgumentException("Missing parameter " + WRESULT);
        }
        LOGGER.debug("Attempting to create an assertion from the token parameter");
        val rsToken = wsFederationHelper.getRequestSecurityTokenFromResult(wResult);
        val assertion = wsFederationHelper.buildAndVerifyAssertion(rsToken, configurations, service);
        if (assertion == null) {
            LOGGER.error("Could not validate assertion via parsing the token from [{}]", WRESULT);
            throw new IllegalArgumentException("Could not validate assertion via the provided token");
        }
        LOGGER.debug("Attempting to validate the signature on the assertion");
        if (!wsFederationHelper.validateSignature(assertion)) {
            val msg = "WS Requested Security Token is blank or the signature is not valid.";
            LOGGER.error(msg);
            throw new IllegalArgumentException(msg);
        }
        buildCredentialsFromAssertion(context, assertion, service);
    }

    private void buildCredentialsFromAssertion(final RequestContext context,
                                               final Pair<Assertion, WsFederationConfiguration> assertion,
                                               final Service service) throws Throwable {
        try {
            LOGGER.debug("Creating credential based on the provided assertion");
            val credential = wsFederationHelper.createCredentialFromToken(assertion.getKey());
            val configuration = assertion.getValue();
            val rpId = wsFederationHelper.getRelyingPartyIdentifier(service, configuration);

View on GitHub (pinned to e7288fc434)