{"record":{"id":"f3fc5a5c6863ea3f","repo":"apereo/cas","slug":"unable-to-determine-the-wa-parameter","errorCode":null,"errorMessage":"Unable to determine the [WA] parameter","messagePattern":"Unable to determine the \\[WA\\] parameter","errorType":"exception","errorClass":"UnauthorizedAuthenticationException","httpStatus":401,"severity":"error","filePath":"support/cas-server-support-ws-idp/src/main/java/org/apereo/cas/ws/idp/web/WSFederationValidateRequestController.java","lineNumber":49,"sourceCode":"    public WSFederationValidateRequestController(final WSFederationRequestConfigurationContext ctx) {\n        super(ctx);\n    }\n\n    /**\n     * Handle federation request.\n     *\n     * @param response the response\n     * @param request  the request\n     * @throws Exception the exception\n     */\n    @GetMapping(path = WSFederationConstants.ENDPOINT_FEDERATION_REQUEST)\n    @Operation(summary = \"Handle federation request\")\n    public void handleFederationRequest(final HttpServletResponse response,\n                                        final HttpServletRequest request) throws Exception {\n        val fedRequest = WSFederationRequest.of(request);\n        val wa = fedRequest.wa();\n        if (StringUtils.isBlank(wa)) {\n            throw new UnauthorizedAuthenticationException(\"Unable to determine the [WA] parameter\", new HashMap<>());\n        }\n\n        switch (wa.toLowerCase(Locale.ENGLISH)) {\n            case WSFederationConstants.WSIGNOUT10, WSFederationConstants.WSIGNOUT_CLEANUP10 -> handleLogoutRequest(fedRequest, request, response);\n            case WSFederationConstants.WSIGNIN10 -> handleInitialAuthenticationRequest(fedRequest, response, request);\n            default -> throw new UnauthorizedAuthenticationException(\"The authentication request is not recognized\", new HashMap<>());\n        }\n    }\n\n    protected void handleLogoutRequest(final WSFederationRequest fedRequest, final HttpServletRequest request,\n                                       final HttpServletResponse response) throws Exception {\n\n        val logoutUrl = FunctionUtils.doIf(StringUtils.isNotBlank(fedRequest.wreply()),\n                () -> {\n                    val service = createService(fedRequest);\n                    val registeredService = getWsFederationRegisteredService(service);\n                    LOGGER.debug(\"Invoking logout operation for request [{}], redirecting next to [{}] matched against [{}]\",\n                        fedRequest, fedRequest.wreply(), registeredService);","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/apereo/cas/blob/e7288fc434b4f4505b8452e1a57e8fb3111bb863/support/cas-server-support-ws-idp/src/main/java/org/apereo/cas/ws/idp/web/WSFederationValidateRequestController.java#L31-L67","documentation":"WS-Federation requests must carry a `wa` (requested action) query parameter such as wsignin1.0 or wsignout1.0. WSFederationValidateRequestController.handleFederationRequest parses the request and throws UnauthorizedAuthenticationException when `wa` is blank, since it cannot dispatch to sign-in or sign-out handling without an action.","triggerScenarios":"A client hits the WS-Federation /federation endpoint (GET/POST handled by handleFederationRequest) and `WSFederationRequest.of(request).wa()` resolves to null or empty string — i.e. the `wa` parameter is absent, empty, or not propagated through a proxy.","commonSituations":"RP-generated sign-in messages missing the wa=wsignin1.0 parameter; reverse proxies or gateways stripping query strings; hand-built deep links to the CAS WS-Fed endpoint copied without full parameters; metadata/claim-rules rewriting the redirect URL and dropping parameters.","solutions":["Ensure the relying party includes `wa=wsignin1.0` (or `wa=wsignout1.0` / `wsignoutcleanup1.0`) in the URL/POST to the CAS WS-Federation endpoint.","Verify the full WS-Fed parameter set (wa, wtrealm, wctx, wreply) is present and that any proxy in front of CAS preserves the query string or form body.","Test with a canonical URL like /cas/ws-idp/federation?wa=wsignin1.0&wtrealm=<realm>&wreply=<url> to confirm the endpoint itself is fine.","If your RP framework omits `wa` on sign-out cleanup requests, configure it to send wsignoutcleanup1.0 explicitly."],"exampleFix":"// before (RP-generated redirect, missing wa)\nresponse.sendRedirect(\"https://cas.example.org/cas/ws-idp/federation?wtrealm=myRealm\");\n// after\nresponse.sendRedirect(\"https://cas.example.org/cas/ws-idp/federation?wa=wsignin1.0&wtrealm=myRealm&wreply=https%3A%2F%2Fapp.example.org%2Fcallback\");","handlingStrategy":"validation","validationCode":"// Before redirecting to the CAS WS-Fed endpoint from an RP:\nif (!request.getParameterMap().containsKey(\"wa\") || request.getParameter(\"wa\").isBlank()) {\n    throw new IllegalArgumentException(\"wa parameter is required (e.g. wsignin1.0)\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always build WS-Fed sign-in messages via a library or constant for wa=wsignin1.0, never by hand.","Test reverse proxies preserve query strings and form bodies for the federation endpoint.","Include wtrealm/wctx/wreply alongside wa in every message."],"tags":["ws-federation","http","sso"],"backgroundTag":"missing-required-argument","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"}