IDPv3.3 and programmatically selecting MFA based on attribute

Ho, PeiQuan PeiQuan.Ho at tufts.edu
Wed Mar 22 13:43:38 EDT 2017


I updated the MFA script to something like below.  But now the SSO is not functioning as expected.  When I log into a site requiring Duo, then SSO to a site that does not, the SSO works.  But when I first login to a site that does not require Duo, then SSO to one that does, the IDP requires a re-login instead of just running the second factor (Duo).

        <![CDATA[
            // defaults to not require Duo
            nextFlow = null;
            duoValue = "urn:tufts.edu:ac:classes:PasswordProtectedTransport: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");
            logger = Java.type("org.slf4j.LoggerFactory").getLogger("edu.internet2.middleware.shibboleth.resolver.Script.eduPersonAssurance");
            logger.info("Checking eduPersonAssurance");
            if (mfaCtx.isAcceptable()) {
                rpCtx = profileContext.getSubcontext("net.shibboleth.idp.profile.context.RelyingPartyContext");
                if (rpCtx != null) {
                    rpId = rpCtx.getRelyingPartyId();
                    logger.info("RelyingParty ID: " + rpId);
                    // Attribute check is required to decide if first factor alone is enough.
                    resCtx = input.getSubcontext(
                        "net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext", true);
                    resCtx.setPrincipal(input.getSubcontext(
                        "net.shibboleth.idp.authn.context.SubjectCanonicalizationContext").getPrincipalName());
                    resCtx.setAttributeRecipientID(rpId);
                    resCtx.getRequestedIdPAttributeNames().add("eduPersonAssurance");
                    resCtx.resolveAttributes(custom);

                    // Check for an attribute that authorizes use of first factor.
                    attribute = resCtx.getResolvedIdPAttributes().get("eduPersonAssurance");
                    valueType =  Java.type("net.shibboleth.idp.attribute.StringAttributeValue");
                    if (attribute != null && attribute.getValues().contains(new valueType(duoValue))) {
                        logger.info("User requires DUO");
                        nextFlow = "authn/Duo";
                    }
                }

                input.removeSubcontext(resCtx);   // cleanup

            }

            nextFlow;   // pass control to second factor or end with the first
        ]]>


Thanks,
-PQ

-----Original Message-----
From: users [mailto:users-bounces at shibboleth.net] On Behalf Of Cantor, Scott
Sent: Tuesday, March 21, 2017 5:08 PM
To: Shib Users <users at shibboleth.net>
Subject: RE: IDPv3.3 and programmatically selecting MFA based on attribute

>   I borrowed this script and have the same issue.  I noticed that when 
> it tries to resolve the attribute during the "checkSecondFactor" step 
> that the values need to resolve my eduPersonAssurance attribute is 
> missing the values that it needs.
> 
> I run logic as the value of requestContext.getPeerEntityId(), but 
> during the first attribute resolution, the value is null

You can't rely on that method, you need to populate the value you want in the AttributeResolutionContext via setAttributeRecipientId and get it from there. You have a bug in your resolver configuration depending on something it shouldn't be.

-- Scott

--
To unsubscribe from this list send an email to users-unsubscribe at shibboleth.net


More information about the users mailing list