apereo/cas · error · IllegalArgumentException
WS Requested Security Token is blank or the signature is…
Error message
WS Requested Security Token is blank or the signature is not valid.
What it means
Thrown by WsFederationResponseValidator.validateWsFederationAuthenticationRequest when WsFederationHelper.validateSignature(assertion) returns false after the assertion was extracted from the WS-Federation security token. It means the SAML assertion could not be cryptographically validated against the identity provider's signing certificate configured in WsFederationConfiguration. CAS refuses to build credentials from an assertion whose signature cannot be trusted.
Solutions
- Verify the signing certificate in WsFederationConfiguration (setSigningCertificate / trust store) matches the current IdP token-signing certificate; re-export the IdP's Token-Signing cert from ADFS and update CAS.
- Confirm the request's wresult security token is complete and unmodified (no HTML-escaping or truncation in transit or in logs/tests).
- Check the IdP did not rotate its signing certificate; fetch the updated federation metadata and update CAS config.
- Enable DEBUG logging on org.apereo.cas.support.wsfederation to see the underlying signature validation failure detail.
Example fix
// before: stale signing cert configured
conf.setSigningCertificate("MIICxDCCAjCg..."); // old ADFS cert
// after: current IdP token-signing certificate
conf.setSigningCertificate(currentAdfsTokenSigningCertBase64); Defensive patterns
Strategy: validation
Validate before calling
// before validation flow, confirm signing key material is present and loadable
if (configuration.getSigningCertificate() == null && configuration.getKeystorePath() == null) {
throw new IllegalStateException("WsFederation configuration has no signing certificate or keystore; token signature validation will fail");
} Type guard
function hasSigningKey(config) {
return Boolean(config.getSigningCertificate?.() || config.getKeystorePath?.());
} Try / catch
try {
validator.validateWsFederationAuthenticationRequest(context);
} catch (IllegalArgumentException e) {
LOGGER.error("WS-Fed token signature invalid; verify IdP signing cert vs CAS config: {}", e.getMessage());
throw new BadWsFederationResponseException("untrusted-token");
} Prevention
- Track IdP certificate rotation (ADFS Token-Signing cert) and update CAS config proactively via federation metadata.
- Keep the signing certificate in a managed keystore and test signature validation after any IdP change.
- Never hand-edit or re-encode captured wresult tokens in tests.
When it happens
Trigger: The security token parses into an assertion but wsFederationHelper.validateSignature fails: the IdP signing certificate/trust store in WsFederationConfiguration does not match the certificate the IdP actually used to sign the token, the token was tampered with or truncated, or the assertion is blank/empty.
Common situations: Misconfigured signing certificate (wrong keystore, wrong alias, expired IdP certificate rotated on the IdP side but not in CAS), importing tokens from a different ADFS/AD FS farm than the one configured, copy-pasting an encoded token that got mangled, or clock/issuer mismatches causing validation helper failures.
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
- Could not validate assertion via the provided token
- Could not extract and identify credentials
- Signing credentials for validation could not be resolved
- Signing credentials for validation could not be resolved…
- Logout request is not signed but should be for service
AI-assisted analysis of apereo/cas@e7288fc434 (2026-09-08).
Data as JSON: /api/errors/957a53d447699e07.
Report an issue: GitHub.
Appendix: source
Thrown at support/cas-server-support-wsfederation-webflow/src/main/java/org/apereo/cas/web/flow/WsFederationResponseValidator.java:71
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);
if (credential == null) {
LOGGER.error("No credential could be extracted from [{}] based on relying party identifier [{}] and identity provider identifier [{}]",
assertion.getKey(), rpId, configuration.getIdentityProviderIdentifier());
throw new IllegalArgumentException("Could not extract and identify credentials");
}View on GitHub (pinned to e7288fc434)