Tavoite
IdP konfiguroidaan pyytämään tunnistetulle käyttäjälle vahvempaa tunnistusta. Kaikki tunnistuspyynnöt tulevat virtuaalikoneen IdP:lle, josta ohjataan tarpeen mukaan MFA:lle.
MPASSid asennus
Projekti https://github.com/Digipalvelutehdas/MPASSid-proxy on valmiiksi käännettynä hakemistossa /home/trainee/MPASSid-proxy. Asennus hyödyntää yhtä sen useista komponenteista.
Alkuvalmistelut
trainee käyttäjällä ei ole oikeuksia muokata IdP:n tiedostoja.
sudo su -
Palautetaan alkuperäinen Session Initiator joka ohjaa käyttäjän discoveryyn proxyn sijasta.
<SSO discoveryProtocol="SAMLDS" discoveryURL="https://testsp.funet.fi/shibboleth/WAYF">SAML2</SSO>
MPASSid jar-tiedostot
Asennetaan jar-tiedostot riippuvuuksineen osaksi IdP:n pakettia. Lisättävät tiedostot kopioidaan hakemistoon /opt/shibboleth-idp/edit-webapp/WEB-INF/lib.
cp /home/trainee/MPASSid-proxy/idp-authn-impl-socialuser/target/idp-authn-impl-socialuser-1.0-SNAPSHOT.jar /opt/shibboleth-idp/edit-webapp/WEB-INF/lib/. cp /home/trainee/MPASSid-proxy/idp-authn-impl-socialuser/target/dependency/* /opt/shibboleth-idp/edit-webapp/WEB-INF/lib/.
JAVA_HOME määritys saadaan asetettua koulutusympäristössä seuraavalla komennolla.
source /etc/default/shibboleth
Kopioidut jar-tiedostot saadaan hallitusti osaksi idp.war tiedostoa ajamalla seuraava komento. Paina Enter, kun asennus kysyy hakemistoa.
/opt/shibboleth-idp/bin/build.sh
Lopulta päivitetty tiedosto voidaan ottaa käyttöön.
systemctl restart shibboleth-idp.service tail -f /opt/shibboleth-idp/logs/idp-process.log
Onnistunut käynnistys päättyy seuraavan kaltaiseen riviin.
2017-01-09 15:06:18,934 - INFO [net.shibboleth.idp.authn.impl.RemoteUserAuthServlet:193] - RemoteUserAuthServlet will process REMOTE_USER, along with attributes [] and headers []
Annotaatiot
Kopioitujen jar-tiedostojen mukana tulee kaksi servletiä. Koulutusympäristön konfiguraatio täytyy muuttaa siten että Jetty etsii määritellystä jar-tiedostosta annotaatiotietoa ja toimii sen mukaan. Etsi tiedostosta <Arg>org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</Arg> ja muokka kyseinen elementti alle olevan kaltaiseksi.
<Call name="setAttribute"> <Arg>org.eclipse.jetty.server.webapp.WebInfIncludeJarPattern</Arg> <Arg>.*/idp-authn-impl-socialuser[^/]*\.jar$</Arg> </Call>
SocialUser vuo-, konfiguraatio- ja näkymä-tiedostot
MPASSid-projektin osana tulee useita autentikointilaajennoksia shibboleth idp 3 tuotteeseen. Kopioimme näihin liittyvät oletuskonfiguraatiot ja näkymät paikoilleen.
cp -r /home/trainee/MPASSid-proxy/idp-authn-impl-socialuser/src/main/resources/conf /opt/shibboleth-idp/. cp -r /home/trainee/MPASSid-proxy/idp-authn-impl-socialuser/src/main/resources/flows /opt/shibboleth-idp/. cp -r /home/trainee/MPASSid-proxy/idp-authn-impl-socialuser/src/main/resources/views /opt/shibboleth-idp/views/.
Tiedostot kopioitiin hakemistoihin joita ei ylikirjoiteta päivityksen yhteydessä.
Tehtävä
Käydään yhdessä läpi asennetut autentikointivuot.
Osion saavutukset
Kopioit MPASSid-projektin riippuvuudet hakemiston /opt/shibboleth-idp/edit-webapp alle, kasasit muokatun idp.war tiedoston ja otit sen käyttöön.
Tämä on se malli jolla sinun tulisi aina tehdä muutokset pakettiin. Hakemiston /opt/shibboleth-idp/edit-webapp kautta lisätty sisältö säilyy myös päivityksen yhteydessä ja tekemäsi muutokset päätyvät aina idp.war-tiedostoon.
Varmistit Jetty konfiguraatiolla että Jetty ottaa käyttöön kaksi tarvittua servletiä.
Kopioit autentikointivuot ja niiden konfiguraatiot paikoilleen.
OpenId Connect konfigurointi
Muokataan SocialUser OpenID Connect - konfiguraatio
Muokataan tiedostoon /opt/shibboleth-idp/flows/authn/SocialUserOpenIDConnect/socialuseropenidconnect-authn-beans.xml mfapilot.funet.fi MFA-proxyn kanssa yhteensopiva OpenID Connect - konfiguraatio.
Korvaa esimerkkien vm0XXX.kaj.pouta.csc.fi oman koneesi nimellä.
MFA-proxy mfa.pilot.funet toteuttaa OpenID Connect autentikoinnin implicit-vuon erikoistapauksena. Lisää alla olevan konfiguraatio tiedostoon.
Lisää JWTPrivateKey-bean ja korvaa SetOIDCInformation -bean esimerkin mukaiseksi. Konfiguraatiossa olevat arvot uid, stepupEPPN ja mobile vastaavat IdP:n resolvoimia attribuutteja. Acr-parametrin arvon oletetaan olevan saman kuin autentikointimetodin arvo. Sekä clientId että redirectURI tulee rekisteröidä MFA-proxy palveluun.
<bean id="JWTPrivateKey" class="net.shibboleth.ext.spring.factory.PrivateKeyFactoryBean" p:resource="../../../credentials/mfaclient.pem" /> <bean id="SetOIDCInformation" class="fi.okm.mpass.idp.authn.impl.SetOIDCInformation" p:privKey-ref="JWTPrivateKey" p:responseType="id_token"> <property name="clientId" value="vm0XXX.kaj.pouta.csc.fi" /> <property name="providerMetadataLocation" value="https://mfapilot.funet.fi" /> <property name="redirectURI" value="https://vm0XXX.kaj.pouta.csc.fi/idp/Authn/SocialUserOpenIdConnectEnd" /> <property name="Acr"> <list> <value>urn:test:stepup</value> </list> </property> <property name="requestClaims"> <map> <entry key="sub" value="uid" /> <entry key="eppn" value="stepupEPPN" /> <entry key="mobile" value="mobile" /> </map> </property> </bean>
Luodaan avain request objectin allekirjoittamiseen
MFA-proxy mfapilot.funet.fi haluaa autentikointipyynnön osana allekirjoitetun request objectin. Tätä varten me luomme ja asennamme avainparin käyttöön.
openssl genrsa -out /opt/shibboleth-idp/credentials/mfaclient.pem 2048 chmod 750 /opt/shibboleth-idp/credentials/mfaclient.pem chown root:jetty /opt/shibboleth-idp/credentials/mfaclient.pem openssl rsa -in /opt/shibboleth-idp/credentials/mfaclient.pem -outform PEM -pubout -out /opt/shibboleth-idp/credentials/mfaclientpublic.pem
Luotu avain pitää vielä muokata JWK muotoon (https://tools.ietf.org/html/rfc7517) ja julkaista.
yum install npm npm install -g pem-jwk mkdir /var/www/vm0XXX.kaj.pouta.csc.fi/www/keyset pem-jwk /opt/shibboleth-idp/credentials/mfaclientpublic.pem > /var/www/vm0XXX.kaj.pouta.csc.fi/www/keyset/mfaclientkeyset.jwk
Testaa että luotu avain löytyy
Konfiguroidaan MFA-vuo Shibbolethille
Konfiguroitu autentikointivuo pitää vielä ottaa käyttöön osana Shibbolethin MFA-vuota.
Lisää uusi authn/SocialUserOpenIDConnect autentikointivuon esittely ja muokkaa vuon authn/MFA esittely esimerkin mukaiseksi.
<!-- only to be used by mfa, not to be activated separately --> <bean id="authn/SocialUserOpenIDConnect" parent="shibboleth.AuthenticationFlow" p:nonBrowserSupported="false" p:forcedAuthenticationSupported="true"> <property name="supportedPrincipals"> <list> <bean parent="shibboleth.SAML2AuthnContextClassRef" c:classRef="urn:test:stepup" /> </list> </property> </bean> <bean id="authn/MFA" parent="shibboleth.AuthenticationFlow" p:passiveAuthenticationSupported="false" p:forcedAuthenticationSupported="true"> <property name="supportedPrincipals"> <list> <bean parent="shibboleth.SAML2AuthnContextClassRef" c:classRef="urn:test:stepup" /> </list> </property> </bean>
Itse MFA-vuo konfiguroidaan tiedostossa /opt/shibboleth-idp/conf/authn/mfa-authn-config.xml. Poista alkuperäinen shibboleth.authn.MFA.TransitionMap-map ja sen viittaama checkSecondFactor-bean. Muokkaa esimerkin mukaiseksi.
Korvaa seuraavasta rivi "]remove]>" rivillä "]]>".
<util:map id="shibboleth.authn.MFA.TransitionMap"> <!-- First rule runs the Password login flow. --> <entry key=""> <bean parent="shibboleth.authn.MFA.Transition" p:nextFlow="authn/Password" /> </entry> <!-- Second rule runs oidc mfa flow if password authentication succeeds. --> <entry key="authn/Password"> <bean parent="shibboleth.authn.MFA.Transition" p:nextFlowStrategy-ref="doSecondFactor" /> </entry> </util:map> <!-- Resolves attributes and then runs oidc mfa flow. --> <bean id="doSecondFactor" parent="shibboleth.ContextFunctions.Scripted" factory-method="inlineScript" p:customObject-ref="shibboleth.AttributeResolverService"> <constructor-arg> <value> <![CDATA[ nextFlow = "authn/SocialUserOpenIDConnect"; // Set up for an attribute lookup. authCtx = input.getSubcontext("net.shibboleth.idp.authn.context.AuthenticationContext"); mfaCtx = authCtx.getSubcontext("net.shibboleth.idp.authn.context.MultiFactorAuthenticationContext"); // Attributes are needed for second factor. resCtx = input.getSubcontext( "net.shibboleth.idp.attribute.resolver.context.AttributeResolutionContext", true); // Look up the username usernameLookupStrategyClass = Java.type("net.shibboleth.idp.session.context.navigate.CanonicalUsernameLookupStrategy"); usernameLookupStrategy = new usernameLookupStrategyClass(); resCtx.setPrincipal(usernameLookupStrategy.apply(input)); resCtx.getRequestedIdPAttributeNames().add("uid"); resCtx.getRequestedIdPAttributeNames().add("stepupEPPN"); resCtx.getRequestedIdPAttributeNames().add("mobile"); resCtx.resolveAttributes(custom); //Pass the resolved attributes to context suCtx = authCtx.getSubcontext("fi.okm.mpass.idp.authn.impl.SocialUserOpenIdConnectContext", true); suCtx.setResolvedIdPAttributes(resCtx.getResolvedIdPAttributes()); input.removeSubcontext(resCtx); nextFlow; // pass control to oidc flow ]remove]> </value> </constructor-arg> </bean>
stepupEPPN
MFA-vuo resolvoi stepupEPPN nimisen attribuutin. Tämä attribuutti pitää määritellä vielä /opt/shibboleth-idp/conf/attribute-resolver.xml tiedostoon. Tarve erilliselle attribuutille tulee siitä että haluamme käsitellä eppn:ää skoopittomana attribuuttina.
<resolver:AttributeDefinition xsi:type="ad:Simple" id="stepupEPPN" sourceAttributeID="eduPersonPrincipalName"> <resolver:Dependency ref="myLDAP" /> </resolver:AttributeDefinition>
Aktivoidaan MFA-vuo
Otetaan MFA-vuo käyttöön yhtenä mahdollisena autentikointivuona.
idp.authn.flows= Password|MFA
Osion saavutukset
Konfiguroit authn/SocialUserOpenIDConnect autentikointivuon toimimaan yhdessä mfapilot.funet.fi MFA-proxyn kanssa.
Otit määritellyn autentikointivuon osaksi MFA-autentikointivuota.
Aktivoit MFA-autentikointivuon.
Käynnistys
Nostetaan vielä logitus sopivalle tasolle.
<!-- Logs MPASSid modules --> <logger name="fi.okm" level="DEBUG"/>
Uudelleen käynnistetään Idp muutoksien voimaan saattamiseksi.
systemctl restart shibboleth-idp.service tail -f /opt/shibboleth-idp/logs/idp-process.log
Toiminnan tarkastelua
Soveltaen aamupäivän osiossa kerrottuja ohjeita kirjaudu käyttämällä vahvempaa tunnistautumista (authnContextClassRef=urn:test:stepup).
Onnistuneen autentikoinnin tarkastelua
Tehtävä 1. Totea onnistunut ja pyydetynmukainen autentikointi tapahtuneeksi.
Tehtävä 2. Tarkastele Shibboleth IdP:n logeista oidc-autentikointivuon toimintaa onnistuneen kirjautumisen yhteydessä.
grep fi.okm.mpass.idp.authn.impl /opt/shibboleth-idp/logs/idp-process.log
Tehtävä 3. Tunnista logeista käytetyt parametriarvot attribuuteille ja niiden resolvoituminen.
Tehtävä 4.Tunnista logeista oidc autentikointipyyntö ja sen mukana lähetetty request object. Tarkastele request objectia selkokielisenä.
Online JWT Decoder
Tehtävä 5. Tunnista logeista vastaus oidc autentikointipyyntöön, etsi siitä id token ja tarkastele sitä selkokielisenä.
Epäonnistuneen autentikoinnin tarkastelua
Tässä osiossa tehdään tarkoituksenmukaisia konfiguraatiovirheitä. Palauta konfiguraatio ennalleen jokaisen kohdan välissä.
grep ValidateOIDCAuthenticationResponse /opt/shibboleth-idp/logs/idp-process.log
Tehtävä 6. Simuloi epäonnistunut rekisteröinti, clientId
Muokkaa clientId parametrin arvoa. MFA proxy ei tunnista rp:tä. Totea epäonnistunut kirjatuminen ja etsi syy logeista.
Tehtävä 7. Simuloi epäonnistunut rekisteröinti, redirectURI
Muokkaa redirectURI parametrin arvoa. MFA proxy ei hyväksy paluuosoitetta. Totea epäonnistuminen selaimesta.
OBS!
Hetkinen, voiko tämä tosiaan toimia näin?
http://openid.net/specs/openid-connect-core-1_0.html#AuthError
Tutkipa hetki asiaa ja tee tarvittaessa issue:
Tehtävä 8. Simuloidaan epäonnistunut rekisteröinti, avain
Luo uusi request objectin allekirjoitusavain ja ota se käyttöön. Totea epäonnistunut kirjatuminen ja etsi syy logeista.