Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The IdP may, however, be configured so that the IdP runs the MFA flow and executes the next flow strategy logic even if the result would normally satisfy the request.

There are two ways to do this, the old way that was a workaround for a missing feature and the new way supported in V3.4.

V3.4+

There is now an explicit property you can set on the login flow descriptor bean in general-authn.xml that attaches a second kind of condition logic to the login flows called a "reuse condition". Think of it as a "SSO or not?" flag on each login method that allows you to customize when the system will reuse a previously built result or re-run the flow. This is possible with any login flow, but it's of particular value with the MFA flow since it generally contains logic that may need to run to determine whether SSO should happen.

...

For more advanced cases or to improve efficiency, a bean can be defined for a script or Java logic that defines the condition to evaluate to decide on reuse, and you can attach that via p:reuseCondition-ref in the usual Spring manner.

Reference

Beans

The beans defined in authn/mfa-authn-config.

V3.3.x and Earlier

A workaround exists in older versions before the problem was fully understood that can usually manage to force the MFA logic to run. To configure this behavior in a scenario involving two login factors:

  1. Add an ordered list of principals with the principal corresponding to your elevated factor first, as the value for the defaultAuthenticationMethods property for the relevant SPs. This is best done via some kind of metadata-based rule, in which you are tagging any SP for which your MFA logic is required to run. As in any case in which you need to rely on this property, you should also ensure that the applicable SPs are required to sign their requests, or if you cannot do so, be sure to disallow the ability for them to request their own context classes (the latter is shown below).

    Code Block
    languagexml
    titleOrdered list of principals for defaultAuthenticationMethods
    collapsetrue
    <bean id="MfaPrincipal" parent="shibboleth.SAML2AuthnContextClassRef" 
      c:classRef="https://refeds.org/profile/mfa" />
    
    <bean id="PasswordPrincipal" parent="shibboleth.SAML2AuthnContextClassRef" 
      c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" />
    
    <bean parent="RelyingPartyByTag">
        <constructor-arg name="candidates">
            <list>
                <bean parent="TagCandidate" c:name="http://macedir.org/entity-category"
                    p:values="http://example.org/mfa-candidate"/>
            </list>
        </constructor-arg>
        <property name="profileConfigurations">
         <list>
           <bean parent="SAML2.SSO" p:disallowedFeatures-ref="SAML2.SSO.FEATURE_AUTHNCONTEXT">
             <property name="defaultAuthenticationMethods">
               <list>
                 <ref bean="MfaPrincipal" />
                 <ref bean="PasswordPrincipal" />
               </list>
              </property>
            </bean>
          </list>
        </property>
    </bean>
  2. You must also ensure idp.authn.favorSSO is unset or set to false in idp.properties.

The combination of the two changes will cause the IdP to always try and produce a result satisfying the first principal even if the user has an active result satisfying the second principal. The result is that the MFA transition strategy logic has a chance to run again.

Note that if the user does have an active result satisfying the first principal, then the IdP will immediately reuse it as long as it satisfies the incoming request (it most likely will of course). So once the MFA transition strategy has run and has produced a result constituted from both factors, it will not run again (modulo forced re-authentication and the lifetime for the result).

What's happening here is that when the "favorSSO" property is false, the IdP more strictly evaluates a request and tries to satisfy the first criteria in the list if it can, even if SSO would allow it to satisfy the second.

Reference

Beans

The beans defined in authn/mfa-authn-config.xml follow:

...

xml follow:

Bean IDTypeDefaultFunction
shibboleth.authn.MFA.TransitionMapMap<String,MultiFactorAuthenticationTransition>
Static ruleset containing the starting point for MFA execution and the rules to use to decide how to do work
shibboleth.authn.MFA.TransitionMapStrategyFunction<ProfileRequestContext,Map<String,MultiFactorAuthenticationTransition>Returns shibboleth.authn.MFA.TransitionMapFunction bean to return the ruleset to use instead of using a static ruleset
shibboleth.authn.MFA.TransitionMultiFactorAuthenticationTransition
Parent bean for defining transition rules in the values of the previous bean's map entries
shibboleth.authn.MFA.validateLoginTransitionsBooleantrueWhether login flows should only be run with regard for forceAuthn/isPassive/nonBrowser conditions
shibboleth.authn.MFA.resultMergingStrategyFunction<ProfileRequestContext,AuthenticationResult>described aboveFunction to run to produce final merged result of MFA login flow during successful completion
shibboleth.authn.MFA.resultCachingPredicatePredicate<ProfileRequestContext>
An optional bean that can be defined to control whether to preserve the authentication result in an IdP session

V2 Compatibility

...

Notes

It's been observed by early deployers, accurately, that the data required to track the use of this feature in the session cache is on the order of 2-3 times as large as just a "simple" authentication result. While it is believed that this remains acceptable with the use of cookies, some storage service implementations such as that for Memcached rely on a less reliable persistence model that may prematurely evict data, so such options may not be a good fit with this feature.