Versions Compared

Key

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

Current File(s): conf/authn/mfa-authn-config.xml, conf/authn/authn.properties (V4.1+)

Format: Native Spring, Properties (V4.1+)

Table of Contents

Overview

...

By itself, the MFA flow is just an orchestration tool and doesn't itself perform any specific kinds of authentication, instead relying on existing login methods to do its work, together with rules you must provide to control behavior. It requires that you plan out what you need to do first, and then implement that plan using Java code or Java Scripting to supply the business logic.

General Configuration

Localtabgroup
Localtab
activetrue
titleV4.0

Use authn/mfa-authn-config.xml to configure this flow.

Localtab
titleV4.1+

Most of the flow configuration is in authn/mfa-authn-config.xml but some generic settings applicable to all login flows are in authn/authn.properties.

Tip

Note that when you use the MFA flow, it's common that it will be the only flow enabled via the idp.authn.flows property. In particular, any flows you direct the MFA flow to run via rules and scripts should not generally be enabled themselves because to do so would may cause the IdP to run them itself in ways that are likely to subvert your intent.

Tip

Another note which is repeated below, regarding the overall method selection process: at the top level, the IdP won't run the MFA login flow at all if its supported principal collection (in authn/general-authn.xml) its supportedPrincipals setting does not satisfy the request. That is, you generally will need to advertise support for all possible custom principals represented by the various factors the MFA flow may produce results for in order to convince the IdP to run it.

As an example, if your MFA processing rules allow for certificate authentication, then you will need to ensure the MFA flow descriptor includes appropriate supported principals reflecting use of certificates, or the IdP won't know it can run the MFA flow for requests for that type of authentication.

A bean called shibboleth.authn.MFA.TransitionMap is commonly defined with contains the map of rules to run to control the transition between flows and determine when to complete work. This is a map whose keys are the flows to "exit" from, and whose values are a bean of the class type net.shibboleth.idp.authn.MultiFactorAuthenticationTransition (a parent bean called shibboleth.authn.MFA.Transition is provided). The first rule is marked with an empty or null key value in the map.

Each transition rule is itself a mapping from the exit state (event) of a flow and the logic to run to decide the next flow to run. There are a couple of simple properties to define transitions to use after a "proceed" event (the usual success indicator), and a more advanced property to supply a full range of event/logic mappings.

...

Hopefully you can see how to adapt it for a similar scenario involving your particular strategy. Obviously the attribute name, values, and the specific flows involved will be specific to youlocal.

This is still a relative simple strategy in that it is driven only by successful results at each step, with errors left to fall through back into the IdP.

...

For full control, you must build a map bean and set it as the value of the nextFlowStrategyMap property of a transition bean. The keys to the map are the events to "catch", and the values of the map can either be a simple String (a subflow to run) or a Function<ProfileRequestContext,String> Function<ProfileRequestContext,String> to run to return the flow to run.

...

The IdP expects/requires a login flow to produce a single AuthenticationResult when it finishes work successfully. To avoid a total redesign, the MFA flow is built to maintain this constraint by combining the individual results it may accumulate in the course of executing into one final result. It does this using a default function that can be overridden by defining a bean named shibboleth.authn.MFA.resultMergingStrategy of type Function< Function<ProfileRequestContext,AuthenticationResult> (i.e., a function that returns the result to use).

...

By default, the MFA flow checks some of the basic parameters of a request and the ability of a login flow to handle them, before running it. That is, it checks things like forced authentication, passive authentication, and non-browser support, before it actually attempts a login flow, even if you signal that it should run one. This is mostly to keep certain kinds of scenarios working automatically without having to be handled in everybody's scripts and rules.

If you want to turn off that behavior, you can supply a bean named shibboleth.authn.MFA.validateLoginTransitions set to a Boolean false constant (V4.0) or set the idp.authn.MFA.validateLoginTransitions property to false (V4.1+)

One thing it doesn't do is apply any activation condition you've attached to the flow descriptor before running the flow. If you want to conditionally run a flow, that's the point of the MFA transition rule logic so you're meant to apply those conditions yourself if you want them. This provides more flexibility since you get to control when the condition applies, which allows, for example, different conditions to attach to the same login method depending on the situation. It's all the same in the end, it's just where the logic runs.

...

Repeating the note at the top of this page: at the top level, the IdP won't run the MFA login flow at all if its supported principal its supportedPrincipals collection does not satisfy the request. That is, you generally will need to advertise support for all possible custom principals represented by the various factors the MFA flow may produce results for in order to convince the IdP to run it. As an example, if your MFA processing rules allow for certificate authentication, then you will need to ensure the MFA flow descriptor includes appropriate supported principals reflecting use of certificates, or the IdP won't know it can run the MFA flow for requests for that type of authentication.

...

There is an explicit property you can set on the login flow descriptor bean in authn/general-authn.xml (V4.0), or by defining a bean and setting a corresponding idp.authn.Flow.reuseCondition property (V4.1+) 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.

You can split these concerns any way you prefer, but if you can include at least some of your logic in the reuse condition rather than the MFA logic itself, that can improve efficiency. But in the simplest case, if you want the MFA rules to run on every request no matter what, just do this:

...

:

Localtabgroup
Localtab
activetrue
titleV4.0
Code Block
languagexml
titleauthn/general-authn.xml
...
		<bean id="authn/MFA" parent="shibboleth.AuthenticationFlow"
                p:passiveAuthenticationSupported="true"
                p:forcedAuthenticationSupported="true"
				p:reuseCondition="false">

			...etc...

        </bean>
...
Localtab
titleV4.1+
Code Block
titleauthn/authn.properties
...
idp.authn.MFA.reuseCondition = shibboleth.Conditions.FALSE
...

That simply says "never reuse results". Bear in mind this is referring to the MFA flow itself, and not the individual "sub factors" that it uses internally to build its results, so individual factors may have results reused when the MFA logic actually runs them, which is generally what is desired.

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 mannerbean by name.

Reference

Beans

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

...