Versions Compared

Key

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

...

Consider a simple example that implements this sequence:

  1. Run the "authn/Flow1" flow.

  2. If Step 1 succeeds, run the "authn/Flow2" flow.

  3. If Step 2 succeeds, combine the results of the two flows into one.

  4. If either Step 1 or 2 fails, return that failure as the MFA flow result.

This simple example doesn't require any logic or scripting:

...

This relatively complex example relies on a single script that does a number of interesting things to achieve the following sequence:

  1. Run the "authn/Flow1" flow.

  2. If Step 1 succeeds and the result is sufficient to satisfy the request, resolve an attribute about the user identified by Step 1.

  3. If the result from Step 1 is sufficient AND the attribute resolved indicates that a user may use that method alone, then finish with the result from Step 1.

  4. If the result from Step 1 is not sufficient OR the attribute resolved indicates that an additional factor is required, run the "authn/Flow2" flow.

  5. If successful, combine the results from the two flows into one.

  6. If either method fails, return that failure as the MFA flow result.

Conditional use of two factors, Flow1 and Flow2

...

Expand
titleFlow Descriptor XML (V4.1+)

To replace the internally defined flow descriptor bean, the following XML is required:

Code Block
languagexml
<util:list id="shibboleth.AvailableAuthenticationFlows">
 
    <bean p:id="authn/MFA" parent="shibboleth.AuthenticationFlow"
            p:order="%{idp.authn.MFA.order:1000}"
            p:nonBrowserSupported="%{idp.authn.MFA.nonBrowserSupported:true}"
            p:passiveAuthenticationSupported="%{idp.authn.MFA.passiveAuthenticationSupported:true}"
            p:forcedAuthenticationSupported="%{idp.authn.MFA.forcedAuthenticationSupported:true}"
            p:proxyRestrictionsEnforced="%{idp.authn.MFA.proxyRestrictionsEnforced:%{idp.authn.enforceProxyRestrictions:true}}"
            p:proxyScopingEnforced="%{idp.authn.MFA.proxyScopingEnforced:false}"
            p:discoveryRequired="%{idp.authn.MFA.discoveryRequired:false}"
            p:lifetime="%{idp.authn.MFA.lifetime:%{idp.authn.defaultLifetime:PT1H}}"
            p:inactivityTimeout="%{idp.authn.MFA.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}"
            p:reuseCondition-ref="#{'%{idp.authn.MFA.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}"
            p:activationCondition-ref="#{'%{idp.authn.MFA.activationCondition:shibboleth.Conditions.TRUE}'.trim()}"
            p:subjectDecorator-ref="#{getObject('%{idp.authn.MFA.subjectDecorator:}'.trim())}">
        <property name="supportedPrincipalsByString">
            <bean parent="shibboleth.CommaDelimStringArray"
                c:_0="#{'%{idp.authn.MFA.supportedPrincipals:}'.trim()}" />
        </property>
    </bean>
 
</util:list>

In older versions and upgraded systems, this list is defined in conf/authn/general-authn.xml. In V4.1+, no default version of the list is provided and it may simply be placed in conf/global.xml if needed.

...