<div dir="ltr">Hi,all<div><br></div><div>When I use nextFlowStrategyMap in MFA Flow, InvalidEvent occurred.<br></div><div><br></div><div>I'll describe the details.</div><div><br></div><div>The error occurs in the flow as described below.</div><div><br></div><div>1. A user accesses the target SP.</div><div>2. MFA Script(described at the end of this email) checks the user's source IP Address includes internalip list.</div><div>3. If  the user's source IP Address includes internalip list and target SP requires MFA, the user is required to select the authentication method(tiqrshib or checkTotpFactor).</div><div>4. If the user selects checkTotpFactor and TOTP Authentication is allowed to be omitted, the error(InvalidEvent) occurs.I found the log as described below.This error occurred at the if-clause which includes the comment "In this if-cluase, the error(InvalidEvent) occurred" in MFA Script at the end of this email.</div>WARN [org.opensaml.profile.action.impl.LogEvent:101] - A non-proceed event occurred while processing the request: InvalidEvent<div><br></div><div>I understand that Returning null in MFA Flow ends the MFA process.</div><div>However, InvalidEvent error occurred in the MFA Flow as described below.</div><div><br></div><div>I'd like to know the solution.</div><div><br></div><div><br></div><div><br></div><div><?xml version="1.0" encoding="UTF-8"?><br><beans xmlns="<a href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a>"<br>       xmlns:context="<a href="http://www.springframework.org/schema/context">http://www.springframework.org/schema/context</a>"<br>       xmlns:util="<a href="http://www.springframework.org/schema/util">http://www.springframework.org/schema/util</a>"<br>       xmlns:p="<a href="http://www.springframework.org/schema/p">http://www.springframework.org/schema/p</a>"<br>       xmlns:c="<a href="http://www.springframework.org/schema/c">http://www.springframework.org/schema/c</a>"<br>       xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>"<br>       xsi:schemaLocation="<a href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a> <a href="http://www.springframework.org/schema/beans/spring-beans.xsd">http://www.springframework.org/schema/beans/spring-beans.xsd</a><br>                           <a href="http://www.springframework.org/schema/context">http://www.springframework.org/schema/context</a> <a href="http://www.springframework.org/schema/context/spring-context.xsd">http://www.springframework.org/schema/context/spring-context.xsd</a><br>                           <a href="http://www.springframework.org/schema/util">http://www.springframework.org/schema/util</a> <a href="http://www.springframework.org/schema/util/spring-util.xsd">http://www.springframework.org/schema/util/spring-util.xsd</a>"<br><br>       default-init-method="initialize"<br>       default-destroy-method="destroy"><br><br>    <util:map id="shibboleth.authn.MFA.TransitionMap"><br>        <entry key=""><br>            <bean parent="shibboleth.authn.MFA.Transition" p:nextFlow="authn/Password" /><br>        </entry><br><br>        <entry key="authn/Password"><br>            <bean parent="shibboleth.authn.MFA.Transition" p:nextFlowStrategy-ref="checkSecondFactor" /><br>        </entry><br><br>        <entry key="custom/methodChooser"><br>            <bean parent="shibboleth.authn.MFA.Transition"><br>                <property name="nextFlowStrategyMap"><br>                    <map><br>                        <entry key="Choosetiqrshib" value="authn/tiqrshib" /><br>                        <entry key="ChooseSiosTotp"     value-ref="checkTotpFactor" /><br>                    </map><br>                </property><br>            </bean><br>        </entry><br><br>    </util:map><br><br>    <bean id="checkSecondFactor" parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript"<br>        p:customObject-ref="shibboleth.HttpServletRequest"><br>        <constructor-arg><br>            <value><br>            <![CDATA[<br>                logger = Java.type("org.slf4j.LoggerFactory").getLogger("net.shibboleth.idp.attribute");<br><br>                // define IP Address which alllows users to access SP withuot MFA<br>                internalIp = ["XXX.XXX.XXX.XXX","YYY.YYY.YYY.YYY"]<br><br>                // define SPs(Entity ID) which require MFA<br>                var mfaList = [<br>                    "<a href="https://sp1.example.org/shibboleth">https://sp1.example.org/shibboleth</a>",<br>                    "<a href="https://sp2.example.org/shibboleth">https://sp2.example.org/shibboleth</a>"<br>                ];<br><br>                // get the source IP Address and the target SP's Entity ID<br>                accessIp = custom.remoteAddr;<br>                rpid = input.getSubcontext("net.shibboleth.idp.profile.context.RelyingPartyContext").relyingPartyId;<br><br>                <a href="http://logger.info">logger.info</a>( '[MFA] SP: '+ rpid );<br>                <a href="http://logger.info">logger.info</a>( '[MFA] clientIP: ' + custom.remoteAddr );<br><br><br>                // compare source IP Address with internal IP Addresses as defined above<br>                matchIp = false;<br>                for (var i = 0, len = internalIp.length; i< len; ++i) {<br>                    if (accessIp.startsWith(internalIp[i])){<br>                            matchIp = true;<br>                    }<br>                }<br><br>                // compare the target SP's Entity ID with SPs' Entity ID List which require MFA as defined above <br>                matchSp = false;<br>                for (var i = 0, len = mfaList.length; i< len; ++i) {<br>                    if (rpid == mfaList[i]){<br>                    matchSp = true;<br>                    }<br>                }<br><br>                // If the target SP require MFA and the target SP's IP Address does not include Internal IP,<br>                // methodChooser is displayed.<br>                if(matchSp == true && matchIp == false){<br>                        nextFlow = "custom/methodChooser";<br>                        <a href="http://logger.info">logger.info</a>( '[MFA] NextFlow: ' + nextFlow );<br>                }else{<br>                    nextFlow = null;<br>                    <a href="http://logger.info">logger.info</a>( '[MFA] NextFlow: ' + 'none' );<br>                }<br><br>                nextFlow; // pass control to second factor or end with the first<br>            ]]><br>            </value><br>        </constructor-arg><br>    </bean><br><br>    <bean id="checkTotpFactor" parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript"<br>        p:customObject-ref="secondFactorHelpersMap"><br>        <constructor-arg><br>            <value><br>            <![CDATA[<br>                nextFlow = null;<br>                logger = Java.type("org.slf4j.LoggerFactory").getLogger("net.shibboleth.idp.authn.impl.TransitionMultiFactorAuthentication");<br><br>                // get login username<br>                usernameLookupStrategyClass = Java.type("net.shibboleth.idp.session.context.navigate.CanonicalUsernameLookupStrategy");<br>                usernameLookupStrategy = new usernameLookupStrategyClass();<br>                username = usernameLookupStrategy.apply(input);<br><br>                // I developed the module which can omit TOTP Authentication for a certain period of time.<br>                // check if TOTP Authentication is allowed to be omitted or not in the code as below<br>                checker = custom.get("totpAuthnSessionChecker");<br>                result = checker.isValidTotpAuthnSession(username);<br><br>                if (result) {<br>                    // return null If TOTP Authentication is allowed to be omitted<br>                    // In this if-cluase, the error(InvalidEvent) occurred<br>                    nextFlow = null;<br>                } else {<br>                    // return next flow(TOTP) If TOTP Authentication is not allowed to be omitted<br>                    nextFlow = "authn/Totp";<br>                }<br><br>                nextFlow;<br>            ]]><br>            </value><br>        </constructor-arg><br>    </bean><br>    <bean id="TotpAuthnSessionChecker"<br>            class="com.sios.idp.shibboleth.common.TotpAuthnSessionChecker" scope="prototype"<br>        p:httpServletRequest-ref="shibboleth.HttpServletRequest" /><br>    <util:map id="secondFactorHelpersMap"><br>        <entry key="attributeResolver" value-ref="shibboleth.AttributeResolverService" /><br>        <entry key="totpAuthnSessionChecker" value-ref="TotpAuthnSessionChecker" /><br>    </util:map><br><br></beans><br></div></div>