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