Uncaught runtime exception on scripted attribute resolution

Francesco Malvezzi francesco.malvezzi at unimore.it
Fri Sep 6 09:52:14 UTC 2024


hi everybody,

I am facing a runtime exception in a MFA flow.

My idea is to setup a MFA flow where, after the authn/Password, user is 
prompted the authn/TOTP according to the presence/absence of a user 
attribute (the TOTP seed in the directory, by the way).

This is my $IDP_HOME/conf/authn/mfa-authn-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:util="http://www.springframework.org/schema/util"
        xmlns:p="http://www.springframework.org/schema/p"
        xmlns:c="http://www.springframework.org/schema/c"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd
 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context.xsd
                            http://www.springframework.org/schema/util 
http://www.springframework.org/schema/util/spring-util.xsd"

        default-init-method="initialize"
        default-destroy-method="destroy">

     <util:map id="shibboleth.authn.MFA.TransitionMap">
         <!-- Run authn/Flow1 first. -->
         <entry key="">
             <bean parent="shibboleth.authn.MFA.Transition" 
p:nextFlow="authn/Password" />
         </entry>

         <!--
         Second rule runs a function if authn/Flow1 succeeds, to 
determine whether an additional
         factor is required.
         -->
         <entry key="authn/Password">
             <bean parent="shibboleth.authn.MFA.Transition" 
p:nextFlowStrategy-ref="checkSecondFactor" />
         </entry>

         <!-- An implicit final rule will return whatever the second 
flow returns. -->
     </util:map>

     <!-- Example script to see if second factor is required. -->
     <bean id="checkSecondFactor" 
parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript"
           p:customObject-ref="shibboleth.AttributeResolverService">
         <constructor-arg>
             <value>
                 <![CDATA[
             nextFlow = "authn/TOTP";

             // Go straight to second factor if we have to, or set up 
for an attribute lookup first.
             authCtx = 
input.getSubcontext("net.shibboleth.idp.authn.context.AuthenticationContext");
             mfaCtx = 
authCtx.getSubcontext("net.shibboleth.idp.authn.context.MultiFactorAuthenticationContext");
             if (mfaCtx.isAcceptable()) {
                 // Attribute check is required to decide if first 
factor alone is enough.
                 resCtx = input.getSubcontext(
 
"net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext", 
true);

				// Look up the username
                 usernameLookupStrategyClass = 
Java.type("net.shibboleth.idp.session.context.navigate.CanonicalUsernameLookupStrategy");
                 usernameLookupStrategy = new usernameLookupStrategyClass();
                 resCtx.setPrincipal(usernameLookupStrategy.apply(input));


				// resolve the attribute to determine if a first factor is sufficient
 
resCtx.getRequestedIdPAttributeNames().add("unimoreTotpSeed");
                 resCtx.resolveAttributes(custom);

                 // Check for an attribute value that authorizes use of 
first factor.
                 attribute = 
resCtx.getResolvedIdPAttributes().get("unimoreTotpSeed");
                 //valueType = 
Java.type("net.shibboleth.idp.attribute.StringAttributeValue");
                 if (attribute != null && attribute.getValues().length() 
 > 0) {
                         nextFlow = "authn/TOTP";
                     }
                     else
                     {
                         nextFlow = null;
                     }

                 input.removeSubcontext(resCtx);   // cleanup
             }

             nextFlow;   // pass control to second factor or end with 
the first
         ]]>
             </value>
         </constructor-arg>
     </bean>
</beans>

Note that it has been lifted from:
https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199505534/MultiFactorAuthnConfiguration
only 4 lines have been changed (flow names and the attribute name).
Please also note I didn't even change the comments from the example. 
They are now somewhat misleading.

In the logs I read (idp-process.log):
2024-09-06 11:21:21,158 - 155.185.3.38 - DEBUG 
[net.shibboleth.idp.authn.AbstractSubjectCanonicalizationAction:225] - 
Profile Action SimpleSubjectCanonicalization: trimming whitespace of 
input string 'this-user'
2024-09-06 11:21:21,159 - 155.185.3.38 - DEBUG 
[net.shibboleth.idp.authn.impl.TransitionMultiFactorAuthentication:195] 
- Profile Action TransitionMultiFactorAuthentication: Preserving 
authentication result from 'authn/Password' flow
2024-09-06 11:21:21,160 - 155.185.3.38 - DEBUG 
[net.shibboleth.idp.authn.impl.TransitionMultiFactorAuthentication:212] 
- Profile Action TransitionMultiFactorAuthentication: Applying MFA 
transition rule to exit state 'authn/Password'
2024-09-06 11:21:21,309 - 155.185.3.38 - ERROR 
[net.shibboleth.idp.authn:35] - Uncaught runtime exception
java.lang.NullPointerException: Cannot invoke 
"java.lang.CharSequence.length()" because "this.text" is null
         at 
java.base/java.util.regex.Matcher.getTextLength(Matcher.java:1769)
2024-09-06 11:21:21,321 - 155.185.3.38 - WARN 
[org.opensaml.profile.action.impl.LogEvent:94] - A non-proceed event 
occurred while processing the request: RuntimeException

the idp-warn.log confirms:

2024-09-06 10:42:00,753 - 155.185.3.38 - ERROR 
[net.shibboleth.idp.authn:35] - Uncaught runtime exception
java.lang.NullPointerException: Cannot invoke 
"java.lang.CharSequence.length()" because "this.text" is null
         at 
java.base/java.util.regex.Matcher.getTextLength(Matcher.java:1769)
         at java.base/java.util.regex.Matcher.reset(Matcher.java:415)
         at java.base/java.util.regex.Matcher.<init>(Matcher.java:252)
         at java.base/java.util.regex.Pattern.matcher(Pattern.java:1134)
         at com.google.common.base.JdkPattern.matcher(JdkPattern.java:36)
         at 
com.google.common.base.Predicates$ContainsPatternPredicate.apply(Predicates.java:662)
         at 
com.google.common.base.Predicates$ContainsPatternPredicate.apply(Predicates.java:651)
         at com.google.common.base.Predicate.test(Predicate.java:79)
         at 
net.shibboleth.shared.logic.StrategyIndirectedPredicate.test(StrategyIndirectedPredicate.java:74)
         at 
java.base/java.util.function.Predicate.lambda$negate$1(Predicate.java:80)
         at 
net.shibboleth.idp.attribute.resolver.AbstractResolverPlugin.resolve(AbstractResolverPlugin.java:174)
         at 
net.shibboleth.idp.attribute.resolver.impl.AttributeResolverImpl.resolveDataConnector(AttributeResolverImpl.java:400)
         at 
net.shibboleth.idp.attribute.resolver.impl.AttributeResolverImpl.resolveDependencies(AttributeResolverImpl.java:453)
         at 
net.shibboleth.idp.attribute.resolver.impl.AttributeResolverImpl.resolveAttributeDefinition(AttributeResolverImpl.java:328)
         at 
net.shibboleth.idp.attribute.resolver.impl.AttributeResolverImpl.resolveAttributes(AttributeResolverImpl.java:244)
         at 
net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext.resolveAttributes(AttributeResolutionContext.java:334)
         at 
org.openjdk.nashorn.internal.scripts.Script$\^eval\_.:program(<eval>:19)
         at 
org.openjdk.nashorn.internal.runtime.ScriptFunctionData.invoke(ScriptFunctionData.java:646)
[...]

line n# 19 is:
resCtx.resolveAttributes(custom);

I already checked the obvious:
1) attribute-resolver loads without errors;
2) aacli.sh works and resolves the TOTP seed attribute.

$ ./bin/version.sh
5.1.3
$ sudo ./bin/plugin.sh -l
INFO  - Including auto-located properties in ./bin/../conf/ldap.properties
INFO  - Including auto-located properties in 
./bin/../conf/saml-nameid.properties
INFO  - Including auto-located properties in 
./bin/../conf/c14n/subject-c14n.properties
INFO  - Including auto-located properties in 
./bin/../conf/services.properties
INFO  - Including auto-located properties in 
./bin/../conf/authn/SpidExternal.properties
INFO  - Including auto-located properties in 
./bin/../conf/authn/X509External.properties
INFO  - Including auto-located properties in 
./bin/../conf/authn/authn.properties
INFO  - Including auto-located properties in 
./bin/../conf/admin/admin.properties
Plugin: net.shibboleth.idp.plugin.nashorn       Current Version: 2.0.0
Plugin: net.shibboleth.idp.plugin.authn.totp    Current Version: 2.1.0

Of course I am not looking in the right place. What did i forget?

(and sorry for the very lenghty post),

Francesco


More information about the users mailing list