Using org.opensaml.profile.logic.IPRangePredicate in MFA nextFlowStrategy

Youssef GHORBAL youssef.ghorbal at pasteur.fr
Fri Apr 4 08:13:02 UTC 2025


> On 4 Apr 2025, at 01:15, Youssef GHORBAL via users <users at shibboleth.net> wrote:
> 
>> On 3 Apr 2025, at 22:46, Peter Schober via users <users at shibboleth.net> wrote:
>> 
>> Youssef GHORBAL via users <users at shibboleth.net> [2025-04-03 22:35 CEST]:
>>> Sorry I wasn’t that clear in my statement. I was meant to say that I
>>> made the logic work using a simple if
>>> (request.getRemoteAddr().startsWith("192.168.42."))
>> 
>> Just supply the IP ranges in CIDR notation instead.
> 
> Sorry, but I still don't get it :(

I've ended up doing it like this (in authn/mfa-authn-config.xml)

    <bean id="InernalRangesCondition" class="org.opensaml.profile.logic.IPRangePredicate"
            p:httpServletRequestSupplier-ref="shibboleth.HttpServletRequestSupplier"
            p:ranges="#{ {'10.0.0.0/8', '192.168.3.0/24', '192.168.18.0/24} }" />

    <!-- Example script to see if second factor is required. Currently just returns the DuoOIDC flow -->
    <bean id="checkSecondFactor" parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript"
            p:customObject-ref="InernalRangesCondition">
        <constructor-arg>
            <value>
                    <![CDATA[
                            // set logging
                            logger = Java.type("org.slf4j.LoggerFactory").getLogger("org.example.duo.script");

                            // default to Duo
                            var nextFlow = "authn/DuoOIDC";

                            // get the Predicate object
                            var internalRangesCheck = custom;

                            // check if client is internal
                            if (internalRangesCheck.test(null)) {
                                logger.info("request excluded from MFA, because in internal IP range");
                                nextFlow = null;
                            }
                            nextFlow;   // pass control to second factor or end with the first
                   ]]>
            </value>
        </constructor-arg>
    </bean>

Thank you for your help! 
Feel free to suggest any enhacement! (for instance If I wanted to log the actual client IP address it's not possible with this approch)

Youssef



More information about the users mailing list