package org.apereo.cas.web.flow.config; import org.apereo.cas.CentralAuthenticationService; import org.apereo.cas.CipherExecutor; import org.apereo.cas.authentication.AuthenticationContextValidator; import org.apereo.cas.authentication.AuthenticationServiceSelectionPlan; import org.apereo.cas.authentication.AuthenticationSystemSupport; import org.apereo.cas.authentication.adaptive.geo.GeoLocationService; import org.apereo.cas.authentication.principal.ResponseBuilderLocator; import org.apereo.cas.configuration.CasConfigurationProperties; import org.apereo.cas.configuration.model.webapp.WebflowProperties; import org.apereo.cas.services.MultifactorAuthenticationProviderSelector; import org.apereo.cas.services.ServicesManager; import org.apereo.cas.ticket.registry.TicketRegistrySupport; import org.apereo.cas.util.cipher.WebflowConversationStateCipherExecutor; import org.apereo.cas.web.flow.CheckWebAuthenticationRequestAction; import org.apereo.cas.web.flow.ClearWebflowCredentialAction; import org.apereo.cas.web.flow.RedirectToServiceAction; import org.apereo.cas.web.flow.authentication.GroovyScriptMultifactorAuthenticationProviderSelector; import org.apereo.cas.web.flow.authentication.RankedMultifactorAuthenticationProviderSelector; import org.apereo.cas.web.flow.resolver.CasDelegatingWebflowEventResolver; import org.apereo.cas.web.flow.resolver.CasWebflowEventResolver; import org.apereo.cas.web.flow.resolver.impl.AdaptiveMultifactorAuthenticationPolicyEventResolver; import org.apereo.cas.web.flow.resolver.impl.InitialAuthenticationAttemptWebflowEventResolver; import org.apereo.cas.web.flow.resolver.impl.RankedAuthenticationProviderWebflowEventResolver; import org.apereo.cas.web.flow.resolver.impl.SelectiveAuthenticationProviderWebflowEventEventResolver; import org.apereo.cas.web.flow.resolver.impl.ServiceTicketRequestWebflowEventResolver; import org.apereo.cas.web.flow.resolver.impl.mfa.AuthenticationAttributeMultifactorAuthenticationPolicyEventResolver; import org.apereo.cas.web.flow.resolver.impl.mfa.GlobalMultifactorAuthenticationPolicyEventResolver; import org.apereo.cas.web.flow.resolver.impl.mfa.GroovyScriptMultifactorAuthenticationPolicyEventResolver; import org.apereo.cas.web.flow.resolver.impl.mfa.PredicatedPrincipalAttributeMultifactorAuthenticationPolicyEventResolver; import org.apereo.cas.web.flow.resolver.impl.mfa.PrincipalAttributeMultifactorAuthenticationPolicyEventResolver; import org.apereo.cas.web.flow.resolver.impl.mfa.RegisteredServiceMultifactorAuthenticationPolicyEventResolver; import org.apereo.cas.web.flow.resolver.impl.mfa.RegisteredServicePrincipalAttributeMultifactorAuthenticationPolicyEventResolver; import org.apereo.cas.web.flow.resolver.impl.mfa.RequestParameterMultifactorAuthenticationPolicyEventResolver; import org.apereo.cas.web.flow.resolver.impl.mfa.RestEndpointMultifactorAuthenticationPolicyEventResolver; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.io.Resource; import org.springframework.web.util.CookieGenerator; import org.springframework.webflow.execution.Action; /** * This is {@link CasCoreWebflowConfiguration}. * * @author Misagh Moayyed * @since 5.0.0 */ @Configuration("casCoreWebflowConfiguration") @EnableConfigurationProperties(CasConfigurationProperties.class) public class CasCoreWebflowConfiguration { @Autowired(required = false) @Qualifier("geoLocationService") private GeoLocationService geoLocationService; @Autowired @Qualifier("authenticationContextValidator") private AuthenticationContextValidator authenticationContextValidator; @Autowired @Qualifier("centralAuthenticationService") private CentralAuthenticationService centralAuthenticationService; @Autowired @Qualifier("defaultAuthenticationSystemSupport") private AuthenticationSystemSupport authenticationSystemSupport; @Autowired @Qualifier("defaultTicketRegistrySupport") private TicketRegistrySupport ticketRegistrySupport; @Autowired @Qualifier("webApplicationResponseBuilderLocator") private ResponseBuilderLocator responseBuilderLocator; @Autowired @Qualifier("servicesManager") private ServicesManager servicesManager; @Autowired @Qualifier("warnCookieGenerator") private CookieGenerator warnCookieGenerator; @Autowired private CasConfigurationProperties casProperties; @Autowired @Qualifier("multifactorAuthenticationProviderSelector") private MultifactorAuthenticationProviderSelector selector; @Autowired @Qualifier("authenticationServiceSelectionPlan") private AuthenticationServiceSelectionPlan authenticationRequestServiceSelectionStrategies; @ConditionalOnMissingBean(name = "adaptiveAuthenticationPolicyWebflowEventResolver") @Bean @RefreshScope public CasWebflowEventResolver adaptiveAuthenticationPolicyWebflowEventResolver() { return new AdaptiveMultifactorAuthenticationPolicyEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector, casProperties, geoLocationService); } @ConditionalOnMissingBean(name = "principalAttributeAuthenticationPolicyWebflowEventResolver") @Bean @RefreshScope public CasWebflowEventResolver principalAttributeAuthenticationPolicyWebflowEventResolver() { return new PrincipalAttributeMultifactorAuthenticationPolicyEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector, casProperties); } @ConditionalOnMissingBean(name = "predicatedPrincipalAttributeMultifactorAuthenticationPolicyEventResolver") @Bean @RefreshScope public CasWebflowEventResolver predicatedPrincipalAttributeMultifactorAuthenticationPolicyEventResolver() { return new PredicatedPrincipalAttributeMultifactorAuthenticationPolicyEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector, casProperties); } @ConditionalOnMissingBean(name = "authenticationAttributeAuthenticationPolicyWebflowEventResolver") @Bean @RefreshScope public CasWebflowEventResolver authenticationAttributeAuthenticationPolicyWebflowEventResolver() { return new AuthenticationAttributeMultifactorAuthenticationPolicyEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector, casProperties); } @ConditionalOnMissingBean(name = "multifactorAuthenticationProviderSelector") @Bean @RefreshScope public MultifactorAuthenticationProviderSelector multifactorAuthenticationProviderSelector() { final Resource script = casProperties.getAuthn().getMfa().getProviderSelectorGroovyScript(); if (script != null) { return new GroovyScriptMultifactorAuthenticationProviderSelector(script); } return new RankedMultifactorAuthenticationProviderSelector(); } @ConditionalOnMissingBean(name = "initialAuthenticationAttemptWebflowEventResolver") @Bean @RefreshScope public CasDelegatingWebflowEventResolver initialAuthenticationAttemptWebflowEventResolver() { final InitialAuthenticationAttemptWebflowEventResolver r = new InitialAuthenticationAttemptWebflowEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector); r.addDelegate(adaptiveAuthenticationPolicyWebflowEventResolver()); r.addDelegate(globalAuthenticationPolicyWebflowEventResolver()); r.addDelegate(requestParameterAuthenticationPolicyWebflowEventResolver()); r.addDelegate(restEndpointAuthenticationPolicyWebflowEventResolver()); r.addDelegate(groovyScriptAuthenticationPolicyWebflowEventResolver()); r.addDelegate(registeredServicePrincipalAttributeAuthenticationPolicyWebflowEventResolver()); r.addDelegate(predicatedPrincipalAttributeMultifactorAuthenticationPolicyEventResolver()); r.addDelegate(principalAttributeAuthenticationPolicyWebflowEventResolver()); r.addDelegate(authenticationAttributeAuthenticationPolicyWebflowEventResolver()); r.addDelegate(registeredServiceAuthenticationPolicyWebflowEventResolver()); r.setSelectiveResolver(selectiveAuthenticationProviderWebflowEventResolver()); return r; } @ConditionalOnMissingBean(name = "restEndpointAuthenticationPolicyWebflowEventResolver") @Bean @RefreshScope public CasWebflowEventResolver restEndpointAuthenticationPolicyWebflowEventResolver() { return new RestEndpointMultifactorAuthenticationPolicyEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector, casProperties); } @ConditionalOnMissingBean(name = "serviceTicketRequestWebflowEventResolver") @Bean @RefreshScope public CasWebflowEventResolver serviceTicketRequestWebflowEventResolver() { return new ServiceTicketRequestWebflowEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector); } @ConditionalOnMissingBean(name = "globalAuthenticationPolicyWebflowEventResolver") @Bean @RefreshScope public CasWebflowEventResolver globalAuthenticationPolicyWebflowEventResolver() { return new GlobalMultifactorAuthenticationPolicyEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector, casProperties); } @ConditionalOnMissingBean(name = "groovyScriptAuthenticationPolicyWebflowEventResolver") @Bean @RefreshScope public CasWebflowEventResolver groovyScriptAuthenticationPolicyWebflowEventResolver() { return new GroovyScriptMultifactorAuthenticationPolicyEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector, casProperties); } @ConditionalOnMissingBean(name = "selectiveAuthenticationProviderWebflowEventResolver") @Bean @RefreshScope public CasWebflowEventResolver selectiveAuthenticationProviderWebflowEventResolver() { return new SelectiveAuthenticationProviderWebflowEventEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector); } @ConditionalOnMissingBean(name = "requestParameterAuthenticationPolicyWebflowEventResolver") @Bean @RefreshScope public CasWebflowEventResolver requestParameterAuthenticationPolicyWebflowEventResolver() { return new RequestParameterMultifactorAuthenticationPolicyEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector, casProperties); } @ConditionalOnMissingBean(name = "registeredServicePrincipalAttributeAuthenticationPolicyWebflowEventResolver") @Bean @RefreshScope public CasWebflowEventResolver registeredServicePrincipalAttributeAuthenticationPolicyWebflowEventResolver() { return new RegisteredServicePrincipalAttributeMultifactorAuthenticationPolicyEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector); } @ConditionalOnMissingBean(name = "registeredServiceAuthenticationPolicyWebflowEventResolver") @Bean @RefreshScope public CasWebflowEventResolver registeredServiceAuthenticationPolicyWebflowEventResolver() { return new RegisteredServiceMultifactorAuthenticationPolicyEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector); } @ConditionalOnMissingBean(name = "rankedAuthenticationProviderWebflowEventResolver") @Bean @RefreshScope public CasWebflowEventResolver rankedAuthenticationProviderWebflowEventResolver() { return new RankedAuthenticationProviderWebflowEventResolver(authenticationSystemSupport, centralAuthenticationService, servicesManager, ticketRegistrySupport, warnCookieGenerator, authenticationRequestServiceSelectionStrategies, selector, authenticationContextValidator, initialAuthenticationAttemptWebflowEventResolver()); } @Bean @RefreshScope public CipherExecutor<byte[], byte[]> webflowCipherExecutor() { final WebflowProperties webflow = casProperties.getWebflow(); return new WebflowConversationStateCipherExecutor( webflow.getEncryption().getKey(), webflow.getSigning().getKey(), webflow.getAlg(), webflow.getSigning().getKeySize(), webflow.getEncryption().getKeySize()); } @Bean @ConditionalOnMissingBean(name = "clearWebflowCredentialsAction") @RefreshScope public Action clearWebflowCredentialsAction() { return new ClearWebflowCredentialAction(); } @Bean @ConditionalOnMissingBean(name = "checkWebAuthenticationRequestAction") @RefreshScope public Action checkWebAuthenticationRequestAction() { return new CheckWebAuthenticationRequestAction(casProperties.getAuthn().getMfa().getContentType()); } @Bean @ConditionalOnMissingBean(name = "redirectToServiceAction") @RefreshScope public Action redirectToServiceAction() { return new RedirectToServiceAction(responseBuilderLocator); } }