Idp/MFAP

Visão Geral

Pre-requisitos

  • Idp Shibboleth v3.3
  • SP MFaProvider

IdP v3.3

            
                $IDP_HOME/conf/idp.properties
            
        
 
# Regular expression matching login flows to enable, 
# e.g. IPAddress|Password
idp.authn.flows= MFA

# Load any additional property resources 
# from a comma-delimited list
idp.additionalProperties= /conf/ldap.properties, 
/conf/saml-nameid.properties, /conf/services.properties, 
/conf/authn/mfaprovider.properties

IdP v3.3

            
                $IDP_HOME/conf/authn/mfaprovider.properties
            
        
 
# Enredeço do MfaProvider  
idp.mfaprovider.apiHost= https://idp2ampto.cafeexpresso.rnp.br/sp/
idp.mfaprovider.username= usuario
idp.mfaprovider.password= senha
$IDP_HOME/conf/authn/mfa-authn-config.xml
            
        
 
<?xmeml version="1.0" encoding="UTF-8"?>
...
    <!--
    This is a map of transition rules that guide the behavior of the MFA flow
    and controls how factors are sequenced, skipped, etc. The key of each entry
    is the name of the step/flow out of which control is passing. The starting
    rule has an empty key.
    
    Each entry is a bean inherited from "shibboleth.authn.MFA.Transition". Per
    the Javadoc for net.shibboleth.idp.authn.MultiFactorAuthenticationTransition:
            
      p:nextFlow (String)
            - A flow to run if the previous step signaled a "proceed" event, for simple
                transitions.
                
      p:nextFlowStrategy (Function<ProfileRequestContext,String>)
            - A function to run if the previous step signaled a "proceed" event, for dynamic
                transitions. Returning null ends the MFA process.
            
      p:nextFlowStrategyMap (Map<String,Object> where Object is String or 
      Function<ProfileRequestContext,String>)
            - Fully dynamic way of expressing control paths. Map is keyed by a previously
                signaled event and the value is a flow to run or a function to
                return the flow to run. Returning null ends the MFA process.
                
    When no rule is provided, there's an implicit "null" that ends the MFA flow
    with whatever event was last signaled. If the "proceed" event from a step is
    the final event, then the MFA process attempts to complete itself successfully.
    -->
<?xmeml version="1.0" encoding="UTF-8"?>
...
      <util:map id="shibboleth.authn.MFA.TransitionMap">
        <!-- First rule runs the IPAddress login flow. -->
       
        <entry key="">
            <bean parent="shibboleth.authn.MFA.Transition" 
                p:nextFlowStrategy-ref="checkFido" />
        </entry>
 
        <entry key="authn/Password">
            <bean parent="shibboleth.authn.MFA.Transition" 
                p:nextFlowStrategy-ref="checkSecondFactor" />
        </entry>
        
      </util:map> 
...
$IDP_HOME/conf/authn/mfa-authn-config.xml
            
        
 
...
<bean id="checkFido" parent="shibboleth.ContextFunctions.Scripted" 
    factory-method="inlineScript"
    p:customObject-ref="shibboleth.AttributeResolverService">
    <constructor-arg>
        <value>
         <![CDATA[
            logger = Java.type("org.slf4j.LoggerFactory").getLogger("net.shibboleth.idp.authn");
            logger.debug("GTAMPTO - nonbrowser = " + input.isBrowserProfile());

            // Check if SAML binding is ECP or "default" (anything else)
            auditCtx = input.getSubcontext("net.shibboleth.idp.profile.context.AuditContext");
            samlAuditFields = Java.type("net.shibboleth.idp.saml.profile.SAMLAuditFields");
            bindings = auditCtx.getFieldValues(samlAuditFields.REQUEST_BINDING);
            iter = bindings.iterator();
            isECP = false;
            nextFlow = "authn/Password"; 
            while (iter.hasNext() && !isECP) {
                b = iter.next();
                logger.debug("GTAMPTO - b = " + b);
                if (b === "urn:oasis:names:tc:SAML:2.0:bindings:SOAP") {
                    isECP = true;
                }
            }
            logger.debug("GTAMPTO - isECP = " + isECP);
            if (isECP){
                nextFlow = "authn/fido-ecp-flow"
            }  
            nextFlow;   // pass control to second factor or end with the first
        ]]>
        </value>
    </constructor-arg>
</bean>
...
<bean id="checkSecondFactor" parent="shibboleth.ContextFunctions.Scripted" 
factory-method="inlineScript"
p:customObject-ref="shibboleth.AttributeResolverService">
<constructor-arg>
    <value>
    <![CDATA[ ... 
	eppnAtt   = resCtx.getResolvedIdPAttributes().get("eduPersonPrincipalName");
	eppn = eppnAtt.getValues().get(0).getValue();
	valueType =  Java.type("net.shibboleth.idp.attribute.StringAttributeValue");
	restsegundofator = Java.type("br.rnp.mfaprovider.mfadialogo.service.MfaService");
	logger.debug("GTAMPTO - eppn  = " + eppn);
	try {
	    segundoFator = new restsegundofator().verifica(eppn); 
	    if (segundoFator=="101")
	        nextFlow = "authn/mfa-dialogo-flow"; 
	    else{
		logger.debug("GTAMPTO - nextflow nulo"); 
		if (mfaCtx.isAcceptable()) { 
			logger.debug("GTAMPTO -mfaCtx.isAcceptable" + mfaCtx.isAcceptable);
			input.removeSubcontext(resCtx);
			nextFlow = null;
		} else {
			input.removeSubcontext(resCtx);
			nextFlow = "authn/mfa-failure-request-flow";			    	
		}
	    }
	}
	catch(err) { ... }
	logger.debug("GTAMPTO MFA nextflow: " + nextFlow);
        nextFlow;   // pass control to second factor or end with the first
    ]]>
    </value>
</constructor-arg>
</bean> 
...
<bean id="authn/mfa-dialogo-flow" parent="shibboleth.AuthenticationFlow"
p:passiveAuthenticationSupported="true"
p:forcedAuthenticationSupported="true"
p:nonBrowserSupported="true">
  <property name="supportedPrincipals">
    <list>
       <bean parent="shibboleth.SAML2AuthnContextClassRef"
         c:classRef="http://id.incommon.org/assurance/mfa" />
       <bean parent="shibboleth.SAML1AuthenticationMethod"
            c:method="http://id.incommon.org/assurance/mfa" />
    </list>
 </property>
</bean>

<bean id="authn/mfa-failure-request-flow" parent="shibboleth.AuthenticationFlow"
 p:passiveAuthenticationSupported="true"  p:forcedAuthenticationSupported="true"  />

<bean id="authn/fido-ecp-flow" parent="shibboleth.AuthenticationFlow"
     p:passiveAuthenticationSupported="true"
     p:forcedAuthenticationSupported="true"
     p:nonBrowserSupported="true" />

...
$IDP_HOME/conf/authn/general-authn.xml
            
        
 
|- $IDP_HOME/flows/authn/
|
|----- mfa-dialogo-flow/mfa-dialogo-flow.xml
|----- fido-ecp-flow/fido-ecp-flow.xml

 

 
<bean id="loginServiceFido"
    class="br.rnp.mfaprovider.mfadialogo.service.LoginServiceFido" 
        scope="prototype"
    p:httpServletRequest-ref="shibboleth.HttpServletRequest" /> 
<var name="loginBean" 
    class="br.rnp.mfaprovider.mfadialogo.bean.LoginBean" />
<var name="loginService" 
    class="br.rnp.mfaprovider.mfadialogo.service.LoginService" />
|- $IDP_HOME/flows/authn/
|
|----- mfa-dialogo-flow/mfa-dialogo-flow.xml
|
|
|
|
|----- fido-ecp-flow/fido-ecp-flow.xml

 

 

Idp/MFAP

By Gabi Cavalcante

Idp/MFAP

  • 347