@Override
    protected Event doInternalExecute(final RequestContext context) {
        val logoutRequests = WebUtils.getLogoutRequests(context);
        if (logoutRequests == null || logoutRequests.isEmpty()) {
            return getFinishLogoutEvent();
        }

        if (casProperties.getSlo().isDisabled()) {
            LOGGER.debug("Single logout callbacks are disabled");
            return getFinishLogoutEvent();
        }

        val logoutUrls = new HashMap<SingleLogoutRequestContext, HttpMessage>();
        logoutRequests
            .stream()
            .filter(sloContext -> sloContext.getStatus() == LogoutRequestStatus.NOT_ATTEMPTED)
            .forEach(sloContext -> {
                LOGGER.debug("Using logout url [{}] for front-channel logout requests", sloContext.getLogoutUrl().toExternalForm());
                logoutExecutionPlan.getSingleLogoutServiceMessageHandlers()
                    .stream()
                    .sorted(Comparator.comparing(SingleLogoutServiceMessageHandler::getOrder))
                    .filter(handler -> handler.supports(sloContext.getExecutionRequest(), sloContext.getService()))
                    .forEach(Unchecked.consumer(handler -> {
                        val logoutMessage = handler.createSingleLogoutMessage(sloContext);
                        LOGGER.debug("Front-channel logout message to send to [{}] is [{}]", sloContext.getLogoutUrl(), logoutMessage);
                        val logoutHttpMessage = handler.prepareLogoutHttpMessageToSend(sloContext, logoutMessage);
                        logoutUrls.put(sloContext, logoutHttpMessage);
                        sloContext.setStatus(LogoutRequestStatus.SUCCESS);
                        sloContext.getService().setLoggedOutAlready(true);
                    }));
            });

        if (!logoutUrls.isEmpty()) {
            WebUtils.putLogoutUrls(context, logoutUrls);
            context.getFlowScope().put("logoutPropagationType", casProperties.getSlo().getLogoutPropagationType());
            return eventFactory.event(this, CasWebflowConstants.TRANSITION_ID_PROPAGATE);
        }

        return getFinishLogoutEvent();
    }
Logout action for front SLO : find the next eligible service and perform front logout.

@author Jerome Leleu
@since 4.0.0
support/cas-server-support-actions-core/src/main/java/org/apereo/cas/web/flow/logout/FrontChannelLogoutAction.java