apereo/cas · error · UnauthorizedAuthenticationException

The authentication request is not recognized

Error message

The authentication request is not recognized

What it means

After reading the `wa` parameter, the controller switches on its lowercase value against WS-Federation actions (wsignin1.0, wsignout1.0, wsignoutcleanup1.0). Any other value falls to the default branch and throws UnauthorizedAuthenticationException, because the requested action is not one CAS's WS-Federation IdP implements.

Solutions

  1. Correct the `wa` value on the relying party to one of wsignin1.0, wsignout1.0, or wsignoutcleanup1.0.
  2. Log/inspect the incoming request URL at CAS to see the exact `wa` string received and compare with WSFederationConstants values.
  3. Check that the RP is actually speaking WS-Federation (not SAML2 or OIDC) against this endpoint, and point other protocols at their proper CAS endpoints.
  4. If a legitimately needed action is unsupported, extend the switch with a custom handler rather than reusing wsignin1.0 semantics.

Example fix

// before (RP sends unrecognized action)
GET /cas/ws-idp/federation?wa=wsignin10&wtrealm=myRealm
// after
GET /cas/ws-idp/federation?wa=wsignin1.0&wtrealm=myRealm
Defensive patterns

Strategy: validation

Validate before calling

Set<String> allowed = Set.of("wsignin1.0", "wsignout1.0", "wsignoutcleanup1.0");
String wa = request.getParameter("wa");
if (wa == null || !allowed.contains(wa.toLowerCase(Locale.ENGLISH))) {
    throw new IllegalArgumentException("Unsupported wa value: " + wa);
}

Prevention

When it happens

Trigger: A request reaches handleFederationRequest with a non-blank `wa` whose value (case-insensitively) is not exactly wsignin1.0, wsignout1.0, or wsignoutcleanup1.0.

Common situations: Typos like wsignin10 or wsign-in1.0 in hand-crafted URLs; a custom or newer WS-Fed action emitted by an unusual RP; an RP sending wauth or another parameter's value where wa is expected; URL-encoding corruption of the value.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at support/cas-server-support-ws-idp/src/main/java/org/apereo/cas/ws/idp/web/WSFederationValidateRequestController.java:55

     *
     * @param response the response
     * @param request  the request
     * @throws Exception the exception
     */
    @GetMapping(path = WSFederationConstants.ENDPOINT_FEDERATION_REQUEST)
    @Operation(summary = "Handle federation request")
    public void handleFederationRequest(final HttpServletResponse response,
                                        final HttpServletRequest request) throws Exception {
        val fedRequest = WSFederationRequest.of(request);
        val wa = fedRequest.wa();
        if (StringUtils.isBlank(wa)) {
            throw new UnauthorizedAuthenticationException("Unable to determine the [WA] parameter", new HashMap<>());
        }

        switch (wa.toLowerCase(Locale.ENGLISH)) {
            case WSFederationConstants.WSIGNOUT10, WSFederationConstants.WSIGNOUT_CLEANUP10 -> handleLogoutRequest(fedRequest, request, response);
            case WSFederationConstants.WSIGNIN10 -> handleInitialAuthenticationRequest(fedRequest, response, request);
            default -> throw new UnauthorizedAuthenticationException("The authentication request is not recognized", new HashMap<>());
        }
    }

    protected void handleLogoutRequest(final WSFederationRequest fedRequest, final HttpServletRequest request,
                                       final HttpServletResponse response) throws Exception {

        val logoutUrl = FunctionUtils.doIf(StringUtils.isNotBlank(fedRequest.wreply()),
                () -> {
                    val service = createService(fedRequest);
                    val registeredService = getWsFederationRegisteredService(service);
                    LOGGER.debug("Invoking logout operation for request [{}], redirecting next to [{}] matched against [{}]",
                        fedRequest, fedRequest.wreply(), registeredService);
                    val logoutParam = getConfigContext().getCasProperties().getLogout().getRedirectParameter().getFirst();
                    return getConfigContext().getCasProperties().getServer().getLogoutUrl()
                        .concat("?").concat(logoutParam).concat("=").concat(service.getId());
                },
                () -> getConfigContext().getCasProperties().getServer().getLogoutUrl())
            .get();

View on GitHub (pinned to e7288fc434)