Step-by-step guide

For Univeristy of Chicago Shibboleth IdP, the following files need to be modified.

Files modified

iam-jetty-base/idp/conf/attribute-resolver.xml
iam-jetty-base/idp/conf/authn/authn-comparison.xml
iam-jetty-base/idp/conf/authn/general-authn.xml
iam-jetty-base/idp/conf/intercept/context-check-intercept-config.xml
iam-jetty-base/idp/flows/authn/checker.groovy

general-authn.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"
       default-init-method="initialize"
       default-destroy-method="destroy">

	<util:list id="shibboleth.AvailableAuthenticationFlows">

		<bean id="authn/IPAddress"
		      parent="shibboleth.AuthenticationFlow"
		      p:passiveAuthenticationSupported="true"
		      p:lifetime="PT60S"
		      p:inactivityTimeout="PT60S">
			<property name="supportedPrincipals">
				<list>
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
					      c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:InternetProtocol" />
				</list>
			</property>
		</bean>

		<bean id="authn/SPNEGO"
		      parent="shibboleth.AuthenticationFlow"
		      p:nonBrowserSupported="false">
			<property name="supportedPrincipals">
				<list>
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
					      c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:Kerberos" />
					<bean parent="shibboleth.SAML1AuthenticationMethod"
					      c:method="urn:ietf:rfc:1510" />
				</list>
			</property>
		</bean>

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

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

		<bean id="authn/RemoteUserInternal"
		      parent="shibboleth.AuthenticationFlow" />

		<bean id="authn/X509"
		      parent="shibboleth.AuthenticationFlow"
		      p:nonBrowserSupported="false">
			<property name="supportedPrincipals">
				<list>
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
					      c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:X509" />
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
					      c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient" />
					<bean parent="shibboleth.SAML1AuthenticationMethod"
					      c:method="urn:ietf:rfc:2246" />
				</list>
			</property>
		</bean>

		<bean id="authn/X509Internal"
		      parent="shibboleth.AuthenticationFlow">
			<property name="supportedPrincipals">
				<list>
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
					      c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:X509" />
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
					      c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:TLSClient" />
					<bean parent="shibboleth.SAML1AuthenticationMethod"
					      c:method="urn:ietf:rfc:2246" />
				</list>
			</property>
		</bean>

		<bean id="authn/Password"
		      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.SAML2AuthnContextClassRef"
                        		      c:classRef="https://refeds.org/profile/sfa" />
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
					      c:classRef="http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password" />
					<bean parent="shibboleth.SAML1AuthenticationMethod"
					      c:method="urn:oasis:names:tc:SAML:1.0:am:password" />
				</list>
			</property>

		</bean>

		<bean id="authn/Duo"
		      parent="shibboleth.AuthenticationFlow"
		      p:forcedAuthenticationSupported="true"
		      p:nonBrowserSupported="false">
			<property name="supportedPrincipals">
				<list>
					<bean parent="shibboleth.SAML1AuthenticationMethod"
					      c:method="http://uchicago.edu/duo" />
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
					      c:classRef="http://uchicago.edu/duo" />
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
                          c:classRef="https://refeds.org/profile/mfa" />
				</list>
			</property>
		</bean>

		<bean id="authn/lfr"
		      parent="shibboleth.AuthenticationFlow"
		      p:forcedAuthenticationSupported="true">
			<property name="supportedPrincipals">
				<list>
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
					      c:classRef="https://uchicago.edu/iam/lfr" />
				</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:InternetProtocol" />
					<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.SAML1AuthenticationMethod"
					      c:method="http://uchicago.edu/duo" />
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
					      c:classRef="http://uchicago.edu/duo" />
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
					      c:classRef="https://uchicago.edu/iam/lfr" />
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
                          c:classRef="https://refeds.org/profile/mfa" />
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
                          c:classRef="https://refeds.org/profile/sfa" />	
					<bean parent="shibboleth.SAML2AuthnContextClassRef"
                          c:classRef="http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password" />
				</list>
			</property>
		</bean>

	</util:list>

	<util:map id="shibboleth.AuthenticationPrincipalWeightMap">
		<entry>
			<key>
				<bean parent="shibboleth.SAML2AuthnContextClassRef"
				      c:classRef="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport" />
			</key>
			<value>1</value>
		</entry>
	</util:map>

</beans>


authn-comparison.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"

       default-init-method="initialize"
       default-destroy-method="destroy">

	<bean id="shibboleth.BetterClassRefMatchFactory" parent="shibboleth.InexactMatchFactory">
		<property name="matchingRules">
			<map>
				<entry key="urn:oasis:names:tc:SAML:2.0:ac:classes:Password">
					<list>
						<value>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</value>
						<value>http://uchicago.edu/duo</value>
						<value>http://id.incommon.org/assurance/silver</value> 
						<value>https://refeds.org/profile/mfa</value> 
					</list>
				</entry>
				<entry key="urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport">
					<list>
						<value>http://uchicago.edu/duo</value>
						<value>https://refeds.org/profile/mfa</value>
					</list>
				</entry>	
			</map>
		</property>
	</bean>

	<bean id="shibboleth.MinimumClassRefMatchFactory" parent="shibboleth.InexactMatchFactory" />
	<bean id="shibboleth.MaximumClassRefMatchFactory" parent="shibboleth.InexactMatchFactory" />
	<bean id="shibboleth.BetterDeclRefMatchFactory" parent="shibboleth.InexactMatchFactory" />
	<bean id="shibboleth.MinimumDeclRefMatchFactory" parent="shibboleth.InexactMatchFactory" />
	<bean id="shibboleth.MaximumDeclRefMatchFactory" parent="shibboleth.InexactMatchFactory" />

	<util:map id="shibboleth.AuthnComparisonRules">

		<!-- Exact matching, this can be left as-is. -->
		<entry key-ref="shibboleth.SAMLAuthnMethodExact" value-ref="shibboleth.ExactMatchFactory"/>
		<entry key-ref="shibboleth.SAMLACClassRefExact" value-ref="shibboleth.ExactMatchFactory"/>
		<entry key-ref="shibboleth.SAMLACDeclRefExact" value-ref="shibboleth.ExactMatchFactory"/>

		<!-- Minimum matching, leave to allow degeneration into exact, or replace with custom rules. -->
		<entry key-ref="shibboleth.SAMLACClassRefMinimum" value-ref="shibboleth.ExactMatchFactory"/>
		<entry key-ref="shibboleth.SAMLACDeclRefMinimum" value-ref="shibboleth.ExactMatchFactory"/>

		<!-- Maximum matching, leave to allow degeneration into exact, or replace with custom rules. -->
		<entry key-ref="shibboleth.SAMLACClassRefMaximum" value-ref="shibboleth.ExactMatchFactory"/>
		<entry key-ref="shibboleth.SAMLACDeclRefMaximum" value-ref="shibboleth.ExactMatchFactory"/>

		<!-- Better matching, refers to empty ruleset that has to be populated to work. -->
		<entry key-ref="shibboleth.SAMLACClassRefBetter" value-ref="shibboleth.BetterClassRefMatchFactory"/>
		<entry key-ref="shibboleth.SAMLACDeclRefBetter" value-ref="shibboleth.BetterDeclRefMatchFactory"/>

	</util:map>

</beans>


context-check-intercept-config
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
                           http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"

       default-init-method="initialize"
       default-destroy-method="destroy">

	<bean id="shibboleth.context-check.Condition" parent="shibboleth.Conditions.AND">
		<constructor-arg>
			<list>
				<bean class="net.shibboleth.idp.profile.logic.AuthnClassPredicate"
                    c:authnClassesToMatch-ref="authnClassesToMatch"
		    c:authnClassesToForgive-ref="authnClassesToForgive" 	
                    c:predicateToDelegate-ref="attributePredicate" />
			</list>
		</constructor-arg>
	</bean>

	<util:set id="authnClassesToMatch">
		<value>http://id.incommon.org/assurance/silver</value>
		<value>http://uchicago.edu/duo</value>
		<value>https://refeds.org/profile/mfa</value>
	</util:set>

	<util:set id="authnClassesToForgive">
		<value>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</value>
		<value>http://schemas.microsoft.com/ws/2008/06/identity/authenticationmethod/password</value>
		<value>https://refeds.org/profile/sfa</value>
	</util:set>

	<bean id="attributePredicate" class="net.shibboleth.idp.profile.logic.SimpleAttributePredicate">
		<property name="attributeValueMap">
			<map>
				<entry key="eduPersonAssurance">
					<list>
						<value>http://id.incommon.org/assurance/silver</value>
						<value>http://uchicago.edu/duo</value>
						<value>https://refeds.org/profile/mfa</value>
					</list>
				</entry>
			</map>
		</property>
	</bean>

</beans>


checker.groovy
//Adding REFEDS expresso profile to secondFactorMap
def secondFactorMap = [
        "http://uchicago.edu/duo": "authn/Duo",
        "http://id.incommon.org/assurance/silver": "authn/Duo",
        "https://refeds.org/assurance/profile/espresso": "authn/Duo"
]
attribute-resolver.xml
<resolver:AttributeDefinition xsi:type="Mapped" xmlns="urn:mace:shibboleth:2.0:resolver:ad"
                        id="eduPersonAssurance" sourceAttributeID="ucisMemberOf">
	<resolver:Dependency ref="directory"/>
	<resolver:AttributeEncoder xsi:type="SAML2String" xmlns="urn:mace:shibboleth:2.0:attribute:encoder"
                                name="urn:oid:1.3.6.1.4.1.5923.1.1.1.11" friendlyName="eduPersonAssurance"/>

	<ValueMap>
		<ReturnValue>http://id.incommon.org/assurance/silver</ReturnValue>
		<SourceValue>uc:reference:account:assurance:silver:authorized</SourceValue>
	</ValueMap>
	<ValueMap>
		<ReturnValue>http://uchicago.edu/duo</ReturnValue>
		<SourceValue>uc:applications:shibboleth:mcb:duo-eligible</SourceValue>
	</ValueMap>
	<ValueMap>
		<ReturnValue>urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport</ReturnValue>
		<SourceValue>uc:applications:shibboleth:mcb:password</SourceValue>
	</ValueMap>
	<ValueMap>
		<ReturnValue>https://refeds.org/assurance/profile/espresso</ReturnValue>
		<SourceValue>uc:reference:account:assurance:refeds:espresso</SourceValue>
	</ValueMap>
	<ValueMap>
		<ReturnValue>https://refeds.org/assurance/profile/cappuccino</ReturnValue>
		<SourceValue>uc:reference:account:assurance:refeds:cappuccino</SourceValue>
	</ValueMap>
</resolver:AttributeDefinition>



There is no content with the specified labels