SPNEGO and _eventId_authn/SPNEGO button

Simon Lundström simlu at su.se
Wed Mar 19 11:32:16 UTC 2025


So close. This broke forceAuthn sadly so I had to work around that:

authn/mfa-authn-config.xml:
<util:map id="shibboleth.authn.MFA.TransitionMap">
<entry key="">
<bean parent="shibboleth.authn.MFA.Transition" p:nextFlowStrategy-ref="tryRemoteUser" />
</entry>

<entry key="authn/RemoteUser">
<bean parent="shibboleth.authn.MFA.Transition">
<property name="nextFlowStrategyMap">
<map>
<entry key="ReselectFlow" value="authn/Password" />
<entry key="RequestUnsupported" value-ref="tryRemoteUser" />
</map>
</property>
</bean>
</entry>

<entry key="authn/Password">
<bean parent="shibboleth.authn.MFA.Transition">
<property name="nextFlowStrategyMap">
<map>
<entry key="trySPNEGO" value-ref="trySPNEGO" />
</map>
</property>
</bean>
</entry>

<entry key="authn/SPNEGO">
<bean parent="shibboleth.authn.MFA.Transition">
<property name="nextFlowStrategyMap">
<map>
<entry key="ReselectFlow" value="authn/Password" />
<entry key="RequestUnsupported" value-ref="trySPNEGO" />
</map>
</property>
</bean>
</entry>

</util:map>

<bean id="trySPNEGO" parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript" >
<constructor-arg>
<value>
<![CDATA[
nextFlow = "authn/SPNEGO";
var logger = Java.type("org.slf4j.LoggerFactory").getLogger("net.shibboleth.idp.authn.SPNEGO.forceAuthn");

authCtx = input.getSubcontext("net.shibboleth.idp.authn.context.AuthenticationContext");
if (authCtx.isForceAuthn()) {
logger.debug("forceAuthn is set, falling back to authn/Password");
nextFlow = "authn/Password";
}

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

<bean id="tryRemoteUser" parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript" >
<constructor-arg>
<value>
<![CDATA[
nextFlow = "authn/RemoteUser";
var logger = Java.type("org.slf4j.LoggerFactory").getLogger("net.shibboleth.idp.authn.RemoteUser.forceAuthn");

authCtx = input.getSubcontext("net.shibboleth.idp.authn.context.AuthenticationContext");
if (authCtx.isForceAuthn()) {
logger.debug("forceAuthn is set, falling back to authn/Password");
nextFlow = "authn/Password";
}

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

idp.properties:
idp.authn.RemoteUser.forcedAuthenticationSupported = true
idp.authn.SPNEGO.forcedAuthenticationSupported = true

Is there a way to “reuse” the logic and “inject” authn/RemoteUser or authn/SPNEGO as an argument somehow somewhere?

BR,
- Simon

> On 17 Mar 2025, at 18:06, Simon Lundström via users <users at shibboleth.net> wrote:
> 
> On Mon, 2025-02-17 at 10:01:12 +0100, Simon Lundström via users wrote:
>> [...] 
>> I haven't found the time yet to investigate using the MFA flow so that's
>> a to be continued.
> 
> Until now!
> 
> So basically what we want is:
> * For the user to try authn/RemoteUser first which via Apaches
>  mod_gssapi and a BrowserMatch enables "true" SPNEGO for browsers that
>  behave well and don't put an NTLM auth popup when SPNEGO fails with
>  GSSAPI (hello Firefox on all OSes and Safari on OS X and Chrome on
>  !Windows)
> * Then we go to authn/Password for the familiar login.vm which includes
>  a "SPNEGO-button" which triggers the custom trySPNEGO event (took a
>  while for me to understand the difference, or that there even is a
>  difference, between flow and event tbh...)
> * There if the user presses the "SPNEGO-button" we try the authn/SPNEGO
>  flow and if that fails we go back to authn/Password with an error
>  "flash".
> 
> We need to configure a custom event[1]:
> authn/mfa-authn-config.xml:
> <end-state id="trySPNEGO" />
> <global-transitions>
> <transition on="trySPNEGO" to="trySPNEGO" />
> <transition on="#{!'proceed'.equals(currentEvent.id)}" to="InvalidEvent" />
> </global-transitions>
> 
> Then we need to configure the MFA flow:
> authn/mfa-authn-config.xml:
> <util:map id="shibboleth.authn.MFA.TransitionMap">
> <entry key="">
> <bean parent="shibboleth.authn.MFA.Transition" p:nextFlow="authn/RemoteUser" />
> </entry>
> <entry key="authn/RemoteUser">
> <bean parent="shibboleth.authn.MFA.Transition">
> <property name="nextFlowStrategyMap">
> <map>
> <entry key="ReselectFlow" value="authn/Password" />
> </map>
> </property>
> </bean>
> </entry>
> <entry key="authn/Password">
> <bean parent="shibboleth.authn.MFA.Transition">
> <property name="nextFlowStrategyMap">
> <map>
> <entry key="trySPNEGO" value="authn/SPNEGO" />
> </map>
> </property>
> </bean>
> </entry>
> <entry key="authn/SPNEGO">
> <bean parent="shibboleth.authn.MFA.Transition">
> <property name="nextFlowStrategyMap">
> <map>
> <entry key="ReselectFlow" value="authn/Password" />
> </map>
> </property>
> </bean>
> </entry>
> </util:map>
> 
> And finally configure the IDP to use the MFA flow:
> idp.properties:
> idp.authn.flows = MFA
> idp.authn.SPNEGO.enforceRun = true
> 
> Three questions:
> 1, Is this an a-OK and supported config? I mean, obviously it works but
> so did how we did before in v3 which doesn't work in v5.
> 2, Why is enforceRun=true needed for SPNEGO to work at all? Even if the
> flow is selected SPNEGO will never be tried unless SPNEGO is forced.
> 3, Is it possible to disable the use of the spnego-unavailable.vm view?
> Right now it just flashes past because of the <body onLoad=""> but it
> would be nice to be able to avoid it completely.
> 
> BR,
> - Simon
> 
> 1,
> <https://shibboleth.atlassian.net/wiki/spaces/IDP5/pages/3199505534/MultiFactorAuthnConfiguration#Custom-Events>
> -- 
> For Consortium Member technical support, see https://shibboleth.atlassian.net/wiki/x/ZYEpPw
> To unsubscribe from this list send an email to users-unsubscribe at shibboleth.net



More information about the users mailing list