SP Requiring/Requesting MFA (was Re: Customizing Second Factor Configuration in mfa-authn-config.xml)

Ullfig, Roberto Alfredo rullfig at uic.edu
Mon Apr 26 17:24:40 UTC 2021


OK then, to NOT do this globally, I define the supported authn in relying-party.xml under DefaultRelyingParty? Here are some of the important bits:

idp.properties:

idp.authn.flows= RemoteUser|MFA

general-authn.xml:

        <bean id="authn/RemoteUser" parent="shibboleth.AuthenticationFlow"
            p:forcedAuthenticationSupported="true"
            p:nonBrowserSupported="false" />

        <bean id="authn/Duo" parent="shibboleth.AuthenticationFlow"
                p:forcedAuthenticationSupported="true"
                p:nonBrowserSupported="false">

            <property name="supportedPrincipals">
                <list>
                    <bean parent="shibboleth.SAML2AuthnContextClassRef"
                        c:classRef="https://refeds.org/profile/mfa" />
                    <bean parent="shibboleth.SAML1AuthenticationMethod"
                        c:method="https://refeds.org/profile/mfa" />
                </list>
            </property>
        </bean>

        <bean id="authn/MFA" parent="shibboleth.AuthenticationFlow"
                p:passiveAuthenticationSupported="true"
                p:forcedAuthenticationSupported="true">

            <property name="supportedPrincipals">
                <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" />
                    <bean parent="shibboleth.SAML2AuthnContextClassRef"
                        c:classRef="https://refeds.org/profile/mfa" />
                    <bean parent="shibboleth.SAML1AuthenticationMethod"
                        c:method="https://refeds.org/profile/mfa" />
                </list>
            </property>
        </bean>

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" p:nextFlowStrategy-ref="checkSecondFactor" />
        </entry>
        <!-- An implicit final rule will return whatever the final flow returns. -->
    </util:map>

    <bean id="checkSecondFactor" parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript"
        p:customObject-ref="shibboleth.AttributeResolverService">
        <constructor-arg>
            <value>
            <![CDATA[
                nextFlow = "authn/Duo";

                // Go straight to second factor if we have to, or set up for an attribute lookup first.
                authCtx = input.getSubcontext("net.shibboleth.idp.authn.context.AuthenticationContext");
                mfaCtx = authCtx.getSubcontext("net.shibboleth.idp.authn.context.MultiFactorAuthenticationContext");
                if (mfaCtx.isAcceptable()) {
                    // Attribute check is required to decide if first factor alone is enough.
                    resCtx = input.getSubcontext(
                        "net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext", true);

                    // Look up the username using a standard function.
                    usernameLookupStrategyClass
                        = Java.type("net.shibboleth.idp.session.context.navigate.CanonicalUsernameLookupStrategy");
                    usernameLookupStrategy = new usernameLookupStrategyClass();
                    resCtx.setPrincipal(usernameLookupStrategy.apply(input));

                    resCtx.getRequestedIdPAttributeNames().add("allowedLoginMethods");
                    resCtx.resolveAttributes(custom);

                    // Check for an attribute that authorizes use of first factor.
                    attribute = resCtx.getResolvedIdPAttributes().get("allowedLoginMethods");
                    valueType =  Java.type("net.shibboleth.idp.attribute.StringAttributeValue");
                    if (attribute != null && attribute.getValues().contains(new valueType("IPAddress"))) {
                        nextFlow = null;
                    }

                    input.removeSubcontext(resCtx);   // cleanup
                }

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

relying-party.xml:

    <bean id="MFASAML2Principal" parent="shibboleth.SAML2AuthnContextClassRef" c:_0="https://refeds.org/profile/mfa" />
    <bean id="Password1" parent="shibboleth.SAML2AuthnContextClassRef" c:_0="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" />
    <bean id="Password2" parent="shibboleth.SAML2AuthnContextClassRef" c:_0="urn:oasis:names:tc:SAML:2.0:ac:classes:Password" />
    <bean id="Password3" parent="shibboleth.SAML1AuthenticationMethod" c:_0="urn:oasis:names:tc:SAML:1.0:am:password" />

    <!--
    Default configuration, with default settings applied for all profiles, and enables
    the attribute-release consent flow.
    -->
    <bean id="shibboleth.DefaultRelyingParty" parent="RelyingParty">
        <property name="profileConfigurations">
            <list>
                <bean parent="Shibboleth.SSO" />
                <ref bean="SAML1.AttributeQuery" />
                <ref bean="SAML1.ArtifactResolution" />
                <bean parent="SAML2.SSO.MDDriven" p:postAuthenticationFlows="#{ {'terms-of-use'} }" />
                <ref bean="SAML2.ECP" />
                <ref bean="SAML2.Logout" />
                <ref bean="SAML2.AttributeQuery" />
                <ref bean="SAML2.ArtifactResolution" />
                <ref bean="Liberty.SSOS" />
<!--
                <bean parent="SAML2.SSO" p:disallowedFeatures-ref="SAML2.SSO.FEATURE_AUTHNCONTEXT">
-->
                <bean parent="SAML2.SSO">
                    <property name="defaultAuthenticationMethods">
                        <list>
                            <ref bean="Password1" />
                            <ref bean="Password2" />
                        </list>
                    </property>
                </bean>
            </list>
        </property>
    </bean>

I still have the same issue with the SP requesting mfa (the one I earlier posted the authn request) as it is here - in this case mfa is done. When I try to force it to Password with SAML2.SSO.FEATURE_AUTHNCONTEXT I get:

2021-04-26 12:20:19,638 - WARN [net.shibboleth.idp.saml.saml2.profile.impl.ProcessRequestedAuthnContext:206] - [9629B65150B337B861D5B9AB63CEC082] - [128.248.2.59] - Profile Action ProcessRequestedAuthnContext: Incoming RequestedAuthnContext disallowed by profile configuration2021-04-26 12:20:19,638 - WARN [org.opensaml.profile.action.impl.LogEvent:101] - [9629B65150B337B861D5B9AB63CEC082] - [128.248.2.59] - A non-proceed event occurred while processing the request: AccessDenied

---
Roberto Ullfig - rullfig at uic.edu
Systems Administrator
Enterprise Applications & Services | Technology Solutions
University of Illinois - Chicago
________________________________
From: users <users-bounces at shibboleth.net> on behalf of Cantor, Scott <cantor.2 at osu.edu>
Sent: Monday, April 26, 2021 10:54 AM
To: Shib Users <users at shibboleth.net>
Subject: Re: SP Requiring/Requesting MFA (was Re: Customizing Second Factor Configuration in mfa-authn-config.xml)

On 4/26/21, 11:49 AM, "users on behalf of Ullfig, Roberto Alfredo" <users-bounces at shibboleth.net on behalf of rullfig at uic.edu> wrote:

>    OK, this SP is sending this:

That doesn't really tell me what it is your IdP is actually programmed to do, but the example material would result in such an IdP honoring first-factor-only both initially and on reuse because the SP is saying that password alone is just fine. Order rarely matters in these cases unless there are very separate and discrete mechanisms in play. Duo doesn't work like that, it's piggybacking on something else.

>If it's not available it ends up using urn:oasis:names:tc:SAML:2.0:ac:classes:Password -  But there's nothing in
> this SP's metadata indicating this.

There is no such metadata to indicate it.

>    The problem here is that if we enable MFA, we can't determine which SPs are passing this authncontext so
> we don't know which applications will be impacted by our change - unless we enable debug mode for a period
> of time and check our logs.

Or you don't do anything globally. But yes, that's true. If you want to know what something is doing, you have to log it. I'm not sure why that would be a revelation or why it's an issue.

As for the logging, no, you don't do it on DEBUG and just look at XML, you audit it. Requested AuthnContext content can be added to the audit log.

-- Scott


--
For Consortium Member technical support, see https://nam04.safelinks.protection.outlook.com/?url=https%3A%2F%2Fwiki.shibboleth.net%2Fconfluence%2Fx%2FcoFAAg&data=04%7C01%7Crullfig%40uic.edu%7C35ebe68ea76940b32c3008d908cb9ad1%7Ce202cd477a564baa99e3e3b71a7c77dd%7C0%7C0%7C637550492843800802%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=ws5QSNBwyLQT5ScPz40ghN6PdDU3UadD41qEOWcwv0g%3D&reserved=0
To unsubscribe from this list send an email to users-unsubscribe at shibboleth.net
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://shibboleth.net/pipermail/users/attachments/20210426/4daa4adb/attachment.htm>


More information about the users mailing list