FunctionAuthnConfiguration

Current File(s): conf/authn/function-authn-config.xml, conf/authn/authn.properties (V4.1+)
Format: Native Spring, Properties (V4.1+)

Overview

The authn/Function login flow is an extension point that allows authentication to be handled by a deployer-supplied Function object, which can be written in Java, a scripting language, etc. It simplifies authoring certain kinds of custom login flows (essentially it provides the "flow" part) and potentially simplifies some MultiFactorAuthnConfiguration scenarios by moving some of the logic into a separate component.

Enabling Module (V4.1+)

For V4.1+, configuring and using this feature requires that you first enable the "idp.authn.Function" module if it isn't already enabled. Systems upgraded from older releases generally come pre-enabled due to the prior state of the configuration tree.

1 2 3 4 5 (Windows) C:\opt\shibboleth-idp> bin\module.bat -t idp.authn.Function || bin\module.bat -e idp.authn.Function (Other) $ bin/module.sh -t idp.authn.Function || bin/module.sh -e idp.authn.Function

General Configuration

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

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

The core of the flow is a required bean named shibboleth.authn.Function.ResultLookupStrategy, of type Function<ProfileRequestContext,Object>

If the Function returns a null, then authentication fails (this is how to signal a controlled failure). Otherwise, the Function can return a String (the username), a Principal, or a Subject, and the system will construct an appropriate AuthenticationResult around whatever is returned.

Use of Cookies

Since a common use case is to be able to read and write cookies, note that there's already a component that handles this called a CookieManager. There are built-in objects of this type that will reuse standard properties controlling cookie domain, path, flags, etc. and that's usually the best way to do things. Simply inject an instance of shibboleth.CookieManager or shibboleth.PersistentCookieManager into a Java-based Function implementation, or as a customObject-ref property of a bean inheriting from shibboleth.ContextFunctions.Scripted or shibboleth.ContextFunctions.Expression, to use it to read and write cookies for you.

Reference

The beans defined, or expected to be defined, in authn/function-authn-config.xml are:

Bean ID / Type

Default

Function

Bean ID / Type

Default

Function

shibboleth.authn.Function.resultLookupStrategy

Function<ProfileRequestContext,Object>

 

A function to produce the authentication result (see above)

shibboleth.authn.Function.resultCachingPredicate

Predicate<ProfileRequestContext>

 

An optional bean that can be defined to control whether to preserve the authentication result in an IdP session

shibboleth.authn.Function.addDefaultPrincipals

Boolean

true

Whether to add the content of the supportedPrincipals property of the underlying flow descriptor to the resulting Subject

The beans defined, or expected to be defined, in authn/function-authn-config.xml are:

Bean ID / Type

Function

Bean ID / Type

Function

shibboleth.authn.Function.resultLookupStrategy

Function<ProfileRequestContext,Object>

A function to produce the authentication result (see above)

shibboleth.authn.Function.resultCachingPredicate

Predicate<ProfileRequestContext>

An optional bean that can be defined to control whether to preserve the authentication result in an IdP session

The general properties configuring this flow via authn/authn.properties are:

Name

Default

Description

Name

Default

Description

idp.authn.Function.order

1000

Flow priority relative to other enabled login flows (lower is "higher" in priority)

idp.authn.Function.nonBrowserSupported

true

Whether the flow should handle non-browser request profiles (e.g., ECP)

idp.authn.Function.passiveAuthenticationSupported

true

Whether the flow allows for passive authentication

idp.authn.Function.forcedAuthenticationSupported

false

Whether the flow supports forced authentication

idp.authn.Function.proxyRestrictionsEnforced

%{idp.authn.enforceProxyRestrictions:true}

Whether the flow enforces upstream IdP-imposed restrictions on proxying

idp.authn.Function.proxyScopingEnforced

false

Whether the flow considers itself to be proxying, and therefore enforces SP-signaled restrictions on proxying

idp.authn.Function.discoveryRequired

false

Whether to invoke IdP-discovery prior to running flow

idp.authn.Function.lifetime

%{idp.authn.defaultLifetime:PT1H}

Lifetime of results produced by this flow

idp.authn.Function.inactivityTimeout

%{idp.authn.defaultTimeout:PT30M}

Inactivity timeout of results produced by this flow

idp.authn.Function.reuseCondition

shibboleth.Conditions.TRUE

Bean ID of Predicate<ProfileRequestContext> controlling result reuse for SSO

idp.authn.Function.activationCondition

shibboleth.Conditions.TRUE

Bean ID of Predicate<ProfileRequestContext> determining whether flow is usable for request

idp.authn.Function.subjectDecorator

 

Bean ID of BiConsumer<ProfileRequestContext,Subject> for subject customization

idp.authn.Function.supportedPrincipals

(see below)

Comma-delimited list of protocol-specific Principal strings associated with flow

idp.authn.Function.addDefaultPrincipals

true

Whether to auto-attach the preceding set of Principal objects to each Subject produced by this flow

Most of the flows, including this one, default to describing themselves in terms of "password"-based authentication, so the supportedPrincipals property defaults to the following XML:

1 2 3 4 5 6 7 8 <list> <bean parent="shibboleth.SAML2AuthnContextClassRef" c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" /> <bean parent="shibboleth.SAML2AuthnContextClassRef" c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:Password" /> <bean parent="shibboleth.SAML1AuthenticationMethod" c:method="urn:oasis:names:tc:SAML:1.0:am:password" /> </list>

In property form, this is expressed as (note especially the trailing commas, which MUST be there):

1 2 3 4 idp.authn.Function.supportedPrincipals = \ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport, \ saml2/urn:oasis:names:tc:SAML:2.0:ac:classes:Password, \ saml1/urn:oasis:names:tc:SAML:1.0:am:password

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

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <util:list id="shibboleth.AvailableAuthenticationFlows"> <bean p:id="authn/Function" parent="shibboleth.AuthenticationFlow" p:order="%{idp.authn.Function.order:1000}" p:nonBrowserSupported="%{idp.authn.Function.nonBrowserSupported:true}" p:passiveAuthenticationSupported="%{idp.authn.Function.passiveAuthenticationSupported:true}" p:forcedAuthenticationSupported="%{idp.authn.Function.forcedAuthenticationSupported:false}" p:proxyRestrictionsEnforced="%{idp.authn.Function.proxyRestrictionsEnforced:%{idp.authn.enforceProxyRestrictions:true}}" p:proxyScopingEnforced="%{idp.authn.Function.proxyScopingEnforced:false}" p:discoveryRequired="%{idp.authn.Function.discoveryRequired:false}" p:lifetime="%{idp.authn.Function.lifetime:%{idp.authn.defaultLifetime:PT1H}}" p:inactivityTimeout="%{idp.authn.Function.inactivityTimeout:%{idp.authn.defaultTimeout:PT30M}}" p:reuseCondition-ref="#{'%{idp.authn.Function.reuseCondition:shibboleth.Conditions.TRUE}'.trim()}" p:activationCondition-ref="#{'%{idp.authn.Function.activationCondition:shibboleth.Conditions.TRUE}'.trim()}" p:subjectDecorator-ref="#{getObject('%{idp.authn.Function.subjectDecorator:}'.trim())}"> <property name="supportedPrincipalsByString"> <bean parent="shibboleth.CommaDelimStringArray" c:_0="#{'%{idp.authn.Function.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.