package org.apereo.cas.web.flow; import org.apache.commons.lang3.StringUtils; import org.apereo.cas.authentication.principal.Service; import org.apereo.cas.configuration.CasConfigurationProperties; import org.apereo.cas.services.RegisteredService; import org.apereo.cas.services.RegisteredServiceAccessStrategy; import org.apereo.cas.services.ServicesManager; import org.apereo.cas.services.UnauthorizedServiceException; import org.apereo.cas.web.support.ArgumentExtractor; import org.apereo.cas.web.support.CookieRetrievingCookieGenerator; import org.apereo.cas.web.support.WebUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.webflow.action.AbstractAction; import org.springframework.webflow.execution.Event; import org.springframework.webflow.execution.RequestContext; import org.springframework.webflow.execution.repository.NoSuchFlowExecutionException; import javax.servlet.http.HttpServletRequest; import java.util.List; /** * Class to automatically set the paths for the CookieGenerators. * <p> * Note: This is technically not threadsafe, but because its overriding with a * constant value it doesn't matter. * <p> * Note: As of CAS 3.1, this is a required class that retrieves and exposes the * values in the two cookies for subclasses to use. * * @author Scott Battaglia * @since 3.1 */ public class InitialFlowSetupAction extends AbstractAction { private static final Logger LOGGER = LoggerFactory.getLogger(InitialFlowSetupAction.class); private final CasConfigurationProperties casProperties; private final ServicesManager servicesManager; private final CookieRetrievingCookieGenerator warnCookieGenerator; private final CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator; private final List<ArgumentExtractor> argumentExtractors; public InitialFlowSetupAction(final List<ArgumentExtractor> argumentExtractors, final ServicesManager servicesManager, final CookieRetrievingCookieGenerator ticketGrantingTicketCookieGenerator, final CookieRetrievingCookieGenerator warnCookieGenerator, final CasConfigurationProperties casProperties) { this.argumentExtractors = argumentExtractors; this.servicesManager = servicesManager; this.ticketGrantingTicketCookieGenerator = ticketGrantingTicketCookieGenerator; this.warnCookieGenerator = warnCookieGenerator; this.casProperties = casProperties; } @Override protected Event doExecute(final RequestContext context) throws Exception { configureCookieGenerators(context); configureWebflowContext(context); configureWebflowContextForService(context); return success(); } private void configureWebflowContextForService(final RequestContext context) { final Service service = WebUtils.getService(this.argumentExtractors, context); if (service != null) { LOGGER.debug("Placing service in context scope: [{}]", service.getId()); final RegisteredService registeredService = this.servicesManager.findServiceBy(service); if (registeredService != null && registeredService.getAccessStrategy().isServiceAccessAllowed()) { LOGGER.debug("Placing registered service [{}] with id [{}] in context scope", registeredService.getServiceId(), registeredService.getId()); WebUtils.putRegisteredService(context, registeredService); final RegisteredServiceAccessStrategy accessStrategy = registeredService.getAccessStrategy(); if (accessStrategy.getUnauthorizedRedirectUrl() != null) { LOGGER.debug("Placing registered service's unauthorized redirect url [{}] with id [{}] in context scope", accessStrategy.getUnauthorizedRedirectUrl(), registeredService.getServiceId()); WebUtils.putUnauthorizedRedirectUrl(context, accessStrategy.getUnauthorizedRedirectUrl()); } } } else if (!casProperties.getSso().isMissingService()) { LOGGER.warn("No service authentication request is available at [{}]. CAS is configured to disable the flow.", WebUtils.getHttpServletRequest(context).getRequestURL()); throw new NoSuchFlowExecutionException(context.getFlowExecutionContext().getKey(), new UnauthorizedServiceException("screen.service.required.message", "Service is required")); } WebUtils.putService(context, service); } private void configureWebflowContext(final RequestContext context) { final HttpServletRequest request = WebUtils.getHttpServletRequest(context); WebUtils.putTicketGrantingTicketInScopes(context, this.ticketGrantingTicketCookieGenerator.retrieveCookieValue(request)); WebUtils.putGoogleAnalyticsTrackingIdIntoFlowScope(context, casProperties.getGoogleAnalytics().getGoogleAnalyticsTrackingId()); WebUtils.putWarningCookie(context, Boolean.valueOf(this.warnCookieGenerator.retrieveCookieValue(request))); WebUtils.putGeoLocationTrackingIntoFlowScope(context, casProperties.getEvents().isTrackGeolocation()); WebUtils.putRecaptchaSiteKeyIntoFlowScope(context, casProperties.getGoogleRecaptcha().getSiteKey()); WebUtils.putStaticAuthenticationIntoFlowScope(context, StringUtils.isNotBlank(casProperties.getAuthn().getAccept().getUsers()) || StringUtils.isNotBlank(casProperties.getAuthn().getReject().getUsers())); WebUtils.putPasswordManagementEnabled(context, casProperties.getAuthn().getPm().isEnabled()); WebUtils.putRememberMeAuthenticationEnabled(context, casProperties.getTicket().getTgt().getRememberMe().isEnabled()); } private void configureCookieGenerators(final RequestContext context) { final String contextPath = context.getExternalContext().getContextPath(); final String cookiePath = StringUtils.isNotBlank(contextPath) ? contextPath + '/' : "/"; if (StringUtils.isBlank(this.warnCookieGenerator.getCookiePath())) { LOGGER.info("Setting path for cookies for warn cookie generator to: [{}] ", cookiePath); this.warnCookieGenerator.setCookiePath(cookiePath); } else { LOGGER.debug("Warning cookie path is set to [{}] and path [{}]", this.warnCookieGenerator.getCookieDomain(), this.warnCookieGenerator.getCookiePath()); } if (StringUtils.isBlank(this.ticketGrantingTicketCookieGenerator.getCookiePath())) { LOGGER.debug("Setting path for cookies for TGC cookie generator to: [{}] ", cookiePath); this.ticketGrantingTicketCookieGenerator.setCookiePath(cookiePath); } else { LOGGER.debug("TGC cookie path is set to [{}] and path [{}]", this.ticketGrantingTicketCookieGenerator.getCookieDomain(), this.ticketGrantingTicketCookieGenerator.getCookiePath()); } } public ServicesManager getServicesManager() { return servicesManager; } }