Hi everyone,
My questions are:
1. For an individual flow based java decoration solution, how can i add flowVariable definition on the password reset flow correctly?
2. Is there a global way of defining custom datas for thmeleaf html using java other than custom groovy script or rest call result?
Any help would be much appreciated.
Details about my problem:
For a custom CAS theming, i wanted to decorate every page with this custom data class:
package tr.com.mycompany.cas.webflow;
import java.io.Serializable;
import java.util.List;
import java.util.Random;
import tr.com.mycompany.cas.utils.AppInfo;
public class WebFlowCustomData implements Serializable {
public String getRegistrationUrl() {
String env = AppInfo.getEnvName();
return String.format(
"https://kayit%s.mycompany.com.tr/reg-form",
"prod".equalsIgnoreCase(env) ? "" : "-" + env
);
}
public String getRandomVideoSrc() {
List<String> vids = List.of(
"/cas/themes/theme2024/img/introDemo.webm",
"/cas/themes/theme2024/img/loop.webm",
"/cas/themes/theme2024/img/intro-light1.webm"
);
return vids.get(new Random().nextInt(3));
}
}Upon reading about Extending CAS Webflow(
https://apereo.github.io/cas/6.6.x/webflow/Webflow-Customization-Extensions.html) page , i tried doing it like this:
First add the customData variables in login and logout flows in this class.
package tr.com.mycompany.cas.webflow;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.web.flow.configurer.AbstractCasWebflowConfigurer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
public class CustomWebFlowDecorator extends AbstractCasWebflowConfigurer {
public CustomWebFlowDecorator(FlowBuilderServices flowBuilderServices,
FlowDefinitionRegistry flowDefinitionRegistry,
ConfigurableApplicationContext applicationContext,
CasConfigurationProperties casProperties) {
super(flowBuilderServices, flowDefinitionRegistry, applicationContext, casProperties);
}
@Override
protected void doInitialize() {
super.createFlowVariable(super.getLoginFlow(), "customData", WebFlowCustomData.class);
super.createFlowVariable(super.getLogoutFlow(), "customData", WebFlowCustomData.class);
}
}And then, to register this class to the configuration i added the class below to the overlay project.
package tr.com.mycompany.cas.webflow;
import org.apereo.cas.configuration.CasConfigurationProperties;
import org.apereo.cas.web.flow.CasWebflowConfigurer;
import org.apereo.cas.web.flow.CasWebflowConstants;
import org.apereo.cas.web.flow.CasWebflowExecutionPlan;
import org.apereo.cas.web.flow.CasWebflowExecutionPlanConfigurer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.webflow.definition.registry.FlowDefinitionRegistry;
import org.springframework.webflow.engine.builder.support.FlowBuilderServices;
@AutoConfiguration
@EnableConfigurationProperties(CasConfigurationProperties.class)
public class WebFlowConfig implements CasWebflowExecutionPlanConfigurer {
@Autowired
private CasConfigurationProperties casProperties;
/**
* flow definition registry for login.
*/
@Autowired
@Qualifier(CasWebflowConstants.BEAN_NAME_LOGIN_FLOW_DEFINITION_REGISTRY)
private FlowDefinitionRegistry loginFlowDefinitionRegistry;
/**
* flow definition registry for logout.
*/
@Autowired
@Qualifier(CasWebflowConstants.BEAN_NAME_LOGOUT_FLOW_DEFINITION_REGISTRY)
private FlowDefinitionRegistry logoutFlowDefinitionRegistry;
@Autowired
private ConfigurableApplicationContext applicationContext;
@Autowired
private FlowBuilderServices flowBuilderServices;
@ConditionalOnMissingBean(name = "loginFlowCustomDecoratorConfigurer")
@Bean
public CasWebflowConfigurer loginFlowCustomDecoratorConfigurer() {
CustomWebFlowDecorator customWebFlowDecorator = new CustomWebFlowDecorator(flowBuilderServices,
loginFlowDefinitionRegistry, applicationContext, casProperties);
customWebFlowDecorator.setLogoutFlowDefinitionRegistry(logoutFlowDefinitionRegistry);
return customWebFlowDecorator;
}
@Override
public void configureWebflowExecutionPlan(final CasWebflowExecutionPlan plan) {
plan.registerWebflowConfigurer(loginFlowCustomDecoratorConfigurer());
}
}and lastly i added this class to spring factories file.
Cas documentation describes only login flow, for adding the same data on logout flow, i checked, autowired the logoutFlowDefinitionRegistry first, and used it on the setLogoutFlowDefinitionRegistry setter method of my CustomWebFlowDecorator. After that CustomWebFlowDecorator's doInitialize flowVariables worked without any problem.
I wanted to add this flow variable inside password reset flow too, and trying to add it like this did not work(null value on thymeleaf htmls and a warning on startup about not setup correctly):
...
protected void doInitialize() {
...
super.createFlowVariable(super.getFlow("pswdreset"), "customData", WebFlowCustomData.class);
...
Have a wonderful day.
Yusuf Gunduz.