package org.apereo.cas.support.saml.services; import org.apereo.cas.authentication.principal.WebApplicationService; import org.apereo.cas.logout.DefaultSingleLogoutServiceLogoutUrlBuilder; import org.apereo.cas.services.RegisteredService; import org.apereo.cas.services.ServicesManager; import org.apereo.cas.support.saml.services.idp.metadata.SamlRegisteredServiceServiceProviderMetadataFacade; import org.apereo.cas.support.saml.services.idp.metadata.cache.SamlRegisteredServiceCachingMetadataResolver; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.net.URL; import java.util.Optional; /** * This is {@link SamlIdPSingleLogoutServiceLogoutUrlBuilder}. * * @author Misagh Moayyed * @since 5.0.0 */ public class SamlIdPSingleLogoutServiceLogoutUrlBuilder extends DefaultSingleLogoutServiceLogoutUrlBuilder { private static final Logger LOGGER = LoggerFactory.getLogger(SamlIdPSingleLogoutServiceLogoutUrlBuilder.class); /** * The Services manager. */ protected ServicesManager servicesManager; /** * The Saml registered service caching metadata resolver. */ protected SamlRegisteredServiceCachingMetadataResolver samlRegisteredServiceCachingMetadataResolver; public SamlIdPSingleLogoutServiceLogoutUrlBuilder(final ServicesManager servicesManager, final SamlRegisteredServiceCachingMetadataResolver resolver) { this.servicesManager = servicesManager; this.samlRegisteredServiceCachingMetadataResolver = resolver; } @Override public URL determineLogoutUrl(final RegisteredService registeredService, final WebApplicationService singleLogoutService) { try { if (registeredService instanceof SamlRegisteredService) { final URL location = buildLogoutUrl(registeredService, singleLogoutService); if (location != null) { LOGGER.info("Final logout URL built for [{}] is [{}]", registeredService, location); return location; } } } catch (final Exception e) { LOGGER.error(e.getMessage(), e); } LOGGER.debug("Service [{}] is not a SAML service, or its logout url could not be determined", registeredService); return super.determineLogoutUrl(registeredService, singleLogoutService); } private URL buildLogoutUrl(final RegisteredService registeredService, final WebApplicationService singleLogoutService) throws Exception { LOGGER.debug("Building logout url for SAML service [{}]", registeredService); final String entityID = singleLogoutService.getId(); LOGGER.debug("Located entity id [{}]", entityID); final Optional<SamlRegisteredServiceServiceProviderMetadataFacade> adaptor = SamlRegisteredServiceServiceProviderMetadataFacade.get(this.samlRegisteredServiceCachingMetadataResolver, SamlRegisteredService.class.cast(registeredService), entityID); if (!adaptor.isPresent()) { LOGGER.warn("Cannot find metadata linked to [{}]", entityID); return null; } final String location = adaptor.get().getSingleLogoutService().getLocation(); return new URL(location); } }