Migrating from 6.6.7 to 7.2.6.When the mfa isnt bypassed in my service, a password reset returns the following message. The mfa works on login, so it's not an unavailable service.Error: jakarta.servlet.ServletException: Request processing failed: org.springframework.webflow.engine.NoMatchingTransitionException: No transition found on occurence of event 'unavailable' in state 'mfa-simple' of flow 'pswdreset' -- valid transitional criteria are array<TransitionCriteria>[resumePasswordReset, success] -- likely programmer error, check the set of TransitionCriteria for this stateIn another environnement still in 6.6, I noticr that there's no mfa when resetting a password, but there's one on login. I dont expect there to be one either (?).Anyone else on 7.2.6+ using simple-mfa without trouble?
package ca.uvic.idm.cas.web.flow; import lombok.extern.slf4j.Slf4j; import lombok.val; 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.ActionState; import org.springframework.webflow.engine.Flow; import org.springframework.webflow.engine.builder.support.FlowBuilderServices; import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException; import java.util.regex.Pattern; @Slf4j public abstract class AbstractUvicCasWebflowConfigurer extends AbstractCasWebflowConfigurer { protected String outputFileName = "/tmp/flow.txt"; public AbstractUvicCasWebflowConfigurer(FlowBuilderServices flowBuilderServices, FlowDefinitionRegistry loginFlowDefinitionRegistry, ConfigurableApplicationContext applicationContext, CasConfigurationProperties casProperties) { super(flowBuilderServices, loginFlowDefinitionRegistry, applicationContext, casProperties); } /** * Inserts an inbound state into a transition for a target state and sets inbound * state's matching transition to the previous target (preserving overall flow). * Inbound state inserts itself into target state by replacing target transition. * @param flow * @param inboundStateId bean identifier for insertable action state * @param inboundActionId action to be performed * @param targetStateid bean identifier for state immediately before inbound * @param targetTransitionId transition point for insertion */ protected ActionState insertIntoFlow( final Flow flow, final String inboundStateId, final String inboundActionId, final String targetStateid, final String targetTransitionId) { val inboundActionState = createActionState(flow, inboundStateId, inboundActionId); val targetState = getState(flow, targetStateid, ActionState.class); val destinationStateId = targetState.getTransition(targetTransitionId).getTargetStateId(); val inboundTransitionSet = inboundActionState.getTransitionSet(); inboundTransitionSet.add(createTransition(targetTransitionId, destinationStateId)); createTransitionForState(targetState, targetTransitionId, inboundStateId, true); flowToFile(flow); return inboundActionState; } protected void flowToFile(final Flow flow) { flowToFile(flow, outputFileName); } protected void flowToFile(final Flow flow, final String fileName) { if (LOGGER.isTraceEnabled()) { String s = flow.toString().trim(); String formatted = formatFlow(s); try (BufferedWriter writer = new BufferedWriter(new FileWriter(fileName))) { // writer.write(s); // writer.write("\n\n\n\n"); writer.write(formatted); } catch (IOException e) { LOGGER.error(e.getMessage()); } } } /** * Formats a spring webflow flow to help determine how to modify a flow. * Adds new lines and indents to make it easier to read. * @param input flow.toString() * @return nicely formatted flow */ public String formatFlow(final String input) { //LOGGER.debug("input: ." + input + "."); // used to add an extra indent for an object's field members java.util.Stack<java.util.AbstractMap.SimpleEntry> stack = new java.util.Stack<>(); int currPosition = 0; String indent = ""; String indentor = "\t"; String newLine = "\n"; // object identifier java.util.regex.Pattern objPattern = Pattern.compile("^(\\w+@\\w+)\\b.*"); String in = input.trim(); StringBuilder out = new StringBuilder(); while (in.length() > currPosition) { java.util.regex.Matcher m = objPattern.matcher(in.substring(currPosition)); String firstTwo = ""; // capture first two characters to match against ']' or '],' if (1 < in.length() - currPosition) { firstTwo = in.substring(currPosition, currPosition + 2); } else { // at end of input firstTwo = in.substring(currPosition, currPosition + 1); } if (in.startsWith("[", currPosition)) { out.append(indent).append(in.charAt(currPosition)).append(newLine); indent += indentor; currPosition++; if (!stack.empty()) { java.util.AbstractMap.SimpleEntry<String, Integer> se = stack.pop(); se.setValue(se.getValue() + 1); stack.push(se); } } else if (firstTwo.startsWith("]")) { if (!stack.empty()) { java.util.AbstractMap.SimpleEntry<String, Integer> se = stack.pop(); if (1 > se.getValue()) { // outdent after printing member variables indent = indent.replaceFirst(indentor, ""); if (!stack.empty()) { // this ] closes from outer object java.util.AbstractMap.SimpleEntry<String, Integer> seOuter = stack.pop(); seOuter.setValue(seOuter.getValue() - 1); stack.push(seOuter); } } else { se.setValue(se.getValue() - 1); stack.push(se); } } indent = indent.replaceFirst(indentor, ""); out.append(indent).append("]"); if ("],".equals(firstTwo)) { out.append(","); currPosition++; } out.append(newLine); currPosition++; } else if (m.matches()) { String obj = m.group(1); out.append(indent).append(obj).append(newLine); indent = indent + indentor; // prepare for members stack.push(new java.util.AbstractMap.SimpleEntry<String, Integer>(obj, 0)); currPosition += obj.length(); } else { int nextOpenBracket = in.indexOf("[", currPosition); int nextCloseBracket = in.indexOf("]", currPosition); int nextComma = in.indexOf(",", currPosition); int nextMark = 0; boolean increaseIndent = false; // if [ or , not found, push beyond last position which would be ] if (0 > nextOpenBracket) { nextOpenBracket = in.length(); } if (0 > nextComma) { nextComma = in.length(); } // add 1 when [ and , since they should remain on same line and ] should be on next line if (nextCloseBracket > nextOpenBracket) { if (nextOpenBracket > nextComma) { nextMark = nextComma + 1; } else { nextMark = nextOpenBracket + 1; // bypass empty and null if ((in.substring(nextMark).startsWith("[empty]]")) || (in.substring(nextMark).startsWith("null]"))) { if (in.substring(nextMark).startsWith("[empty]],")) { nextMark += 9; } else if (in.substring(nextMark).startsWith("[empty]]")) { nextMark += 8; } else if (in.substring(nextMark).startsWith("null],")) { nextMark += 6; } else if (in.substring(nextMark).startsWith("null]")) { nextMark += 5; } } else { // indent members increaseIndent = true; if (!stack.empty()) { java.util.AbstractMap.SimpleEntry<String, Integer> se = stack.pop(); se.setValue(se.getValue() + 1); stack.push(se); } } } } else if (nextCloseBracket > nextComma) { nextMark = nextComma + 1; } else { nextMark = nextCloseBracket; } String s = in.substring(currPosition, nextMark).trim(); if (0 < s.length()) { out.append(indent).append(s).append(newLine); currPosition = nextMark; } if (increaseIndent) { // for next line indent = indent + indentor; } } } String formatted = out.toString().trim(); //LOGGER.debug("formatted: ." + formatted + "."); return formatted; } }
You received this message because you are subscribed to a topic in the Google Groups "CAS Community" group.
To unsubscribe from this topic, visit https://groups.google.com/a/apereo.org/d/topic/cas-user/b-qDsXp3_m4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to cas-user+u...@apereo.org.
To view this discussion visit https://groups.google.com/a/apereo.org/d/msgid/cas-user/YQBP288MB0081FAE67FA2EC1B9F183E07CEF6A%40YQBP288MB0081.CANP288.PROD.OUTLOOK.COM.
Controls whether password reset operations must activate and support a multifactor authentication flow based on the set of available MFA providers that are configured and active, before reset instructions can be shared and sent.