private void handleLogoutRequest(final HttpServletResponse response, final HttpServletRequest request,
                                     final Pair<? extends SignableSAMLObject, MessageContext> pair,
                                     final String logoutRequestBinding) throws Throwable {
        val logoutRequest = (LogoutRequest) pair.getKey();
        val messageContext = pair.getValue();

        val entityId = SamlIdPUtils.getIssuerFromSamlObject(logoutRequest);
        LOGGER.trace("SAML logout request from entity id [{}] is signed", entityId);

        val service = configurationContext.getWebApplicationServiceFactory().createService(entityId);
        service.getAttributes().put(SamlProtocolConstants.PARAMETER_ENTITY_ID, CollectionUtils.wrapList(entityId));
        val registeredService = configurationContext.getServicesManager().findServiceBy(service, SamlRegisteredService.class);
        val audit = AuditableContext.builder()
            .service(service)
            .registeredService(registeredService)
            .httpRequest(request)
            .httpResponse(response)
            .build();
        val accessResult = configurationContext.getRegisteredServiceAccessStrategyEnforcer().execute(audit);
        accessResult.throwExceptionIfNeeded();
        LOGGER.trace("SAML registered service tied to [{}] is [{}]", entityId, registeredService);

        ensureLogoutRequestIsSignedIfNecessary(registeredService, messageContext);

        val facade = SamlRegisteredServiceMetadataAdaptor.get(
            configurationContext.getSamlRegisteredServiceCachingMetadataResolver(), registeredService, entityId).orElseThrow();
        if (SAMLBindingSupport.isMessageSigned(messageContext)) {
            LOGGER.trace("Verifying signature on the SAML logout request for [{}]", entityId);
            configurationContext.getSamlObjectSignatureValidator()
                .verifySamlProfileRequest(logoutRequest, facade, request, messageContext);
        }
        configurationContext.getOpenSamlConfigBean().logObject(logoutRequest);

        val logoutUrls = SingleLogoutUrl.from(registeredService);
        if (!logoutUrls.isEmpty()) {
            val destination = logoutUrls.getFirst().getUrl();
            WebUtils.putLogoutRedirectUrl(request, destination);
        }

        WebUtils.putRegisteredService(request, registeredService);

        val extensions = buildSamlObject(Extensions.DEFAULT_ELEMENT_NAME, Extensions.class);
        val bindingAttribute = buildSamlObject(RequestInitiator.DEFAULT_ELEMENT_NAME, RequestInitiator.class);
        bindingAttribute.setBinding(logoutRequestBinding);
        extensions.getUnknownXMLObjects().add(bindingAttribute);
        logoutRequest.setExtensions(extensions);

        try (val writer = SamlUtils.transformSamlObject(configurationContext.getOpenSamlConfigBean(), logoutRequest)) {
            val encodedRequest = EncodingUtils.encodeBase64(writer.toString().getBytes(StandardCharsets.UTF_8));
            WebUtils.putSingleLogoutRequest(request, encodedRequest);
        }

        configurationContext.getApplicationContext()
            .getBeansOfType(SamlIdPProfileSingleLogoutRequestProcessor.class)
            .values()
            .stream()
            .filter(BeanSupplier::isNotProxy)
            .sorted(AnnotationAwareOrderComparator.INSTANCE)
            .filter(processor -> processor.supports(request, response, logoutRequest, messageContext))
            .forEach(Unchecked.consumer(processor -> processor.receive(request, response, logoutRequest, messageContext)));

        val requestDispatcher = request.getServletContext().getRequestDispatcher(CasProtocolConstants.ENDPOINT_LOGOUT);
        requestDispatcher.forward(request, response);
    }
This is {@link AbstractSamlSLOProfileHandlerController}.

@author Misagh Moayyed
@since 5.1.0
support/cas-server-support-saml-idp-web/src/main/java/org/apereo/cas/support/saml/web/idp/profile/slo/AbstractSamlSLOProfileHandlerController.java