Multi-Factor Authentication in SAML

Request two-step login with a Shibboleth service provider 

The Shibboleth Service Provider is the most frequently used SAML implementation in our federation and worldwide in academic identity federations. Requesting multi-factor authentication can be achieved via the following options:

A. By edu-ID Resource Registry

The easiest way to request MFA is to enable the checkbox "REFEDS Multifactor Authentication Login" in the "Intended Audience and Expert Settings" for a service in the edu-ID Resource Registry. This enforces MFA for all users if they log in via the Switch edu-ID service. But be careful: This setting has no effect for users from Identity Providers that have not adopted Switch edu-ID. I.e. all users from non-Swiss Identity Providers and users from non-green organisations on this map. Therefore, this option has to be used very carefully!

Recommendation: use this option if MFA is to be enforced for all users of organisations who have adopted edu-ID, without excluding users of organizations without edu-ID adoption.

B. By service configuration with Shibboleth

The Shibboleth Service Provider can request MFA to access certain directories or files. This can either be achieved via an Apache config or .htacess directive (more examples here) like the following one that requires the edu-ID user to perform the two-step login/MFA and to be a staff member:

<Directory /var/www/mfa-secured>
  AuthType shibboleth
  ShibRequestSetting requireSession true
ShibRequestSetting authnContextClassRef https://refeds.org/profile/mfa <RequireAll> Require shib-attr affiliation staff Require authnContextClassRef https://refeds.org/profile/mfa </RequireAll> </Directory>

or for non-Apache web servers within the Shibboleth SP itself via an XML Access Control rule in the RequestMap element like in this example:

<RequestMap applicationId="default">
    <Host name="example.org">
        <Path 
          name="mfa-secured" 
          authType="shibboleth"
          requireSession="true"
          authnContextClassRef="https://refeds.org/profile/mfa">
            <AccessControl>
                <AND>
                    <Rule require="affiliation">staff</Rule>
                    <Rule require="authnContextClassRef">https://refeds.org/profile/mfa</Rule>
                </AND>
            </AccessControl>
        </Path>
    </Host>
</RequestMap> 

In both above cases, the Shibboleth Service Provider will ensure that users can access the protected content only if they successfully could be authenticated with two-step login.

C. By specifically triggering it via URL

An application can also request MFA when it is required for a specific user. It just needs to send the user to a Shibboleth SessionInitiator (default is /Shibboleth.sso/Login) with the GET request parameter 'authnContextClassRef' and the value 'https://refeds.org/profile/mfa'. In case of an edu-ID user, two-step login would be enforced by sending the user to the following relative URL on a host example.org with a Shibboleth Service Provider installed:

https://example.org/Shibboleth.sso/Login?entityID=https%3A%2F%2Feduid.ch%2Fidp%2Fshibboleth&authnContextClassRef=https%3A%2F%2Frefeds.org%2Fprofile%2Fmfa

Notes:

  • By adding an additional 'target' GET parameter to the above URL, a URL can be specified to which the user should return after authentication.
  • The example link above shows a request to the edu-ID IdP (entityID=https://eduid.ch/idp/shibboleth). For classic SPs, the entityID as to be adapted to the IdP where the user was authenticated.

D. Enabling MFA for other SAML service providers

https://cms.www.switch.ch/eduid/docs/services/openid-connect/mfa/

SAML Service Providers other than Shibboleth can request two-step login by sending an authentication request that requests the SAML authenticationContextClass https://refeds.org/profile/mfa.

A SAML authentication request then would look like this:

<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                    [...]
                    ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST"
                    Version="2.0">
  <saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">#SP EntityID#</saml:Issuer>
  <samlp:NameIDPolicy AllowCreate="1" />
  <samlp:RequestedAuthnContext>
    <saml:AuthnContextClassRef xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">https://refeds.org/profile/mfa</saml:AuthnContextClassRef>
  </samlp:RequestedAuthnContext>
</samlp:AuthnRequest>

Note

When the user returns to the service authenticated, the application should always check that MFA was performed. For Shibboleth the web server environment variable 'Shib-AuthnContext-Class' should contain the value 'https://refeds.org/profile/mfa'

Example services

An example service that requests MFA (for users who enabled it) is the edu-ID account management site. Also, the edu-ID Attribute Viewer can trigger two-step login by clicking on "Request Login with MFA" after you logged in with username/password only, or by using this enforcing link.

MFA with three factors

If the (network) location of a user is also considered as a factor, enforcing a three-factor authentication requiring the user to be in a particular network on top of the two-step login can also be achieved with a Shibboleth SP.

Sample access control rule for Apache:

<Directory /opt/www/administrator>
  AuthType shibboleth
  ShibRequestSetting requireSession true
  ShibRequestSetting authnContextClassRef https://refeds.org/profile/mfa

  <RequireAll>
   # Require first factor: username and password
   Require valid-user

   # Require second factor: one-time code
   Require authnContextClassRef https://refeds.org/profile/mfa

   # Require third factor: be within own network
   <RequireAny>
     Require ip 203.0.113.0/24
     Require ip 202::/16
   </RequireAny>

  </RequireAll>
</Directory>

Not requiring MFA for some organisations

There can be cases where MFA should be enforced only for users of some organisations but not for others. Users from organisations abroad (via eduGAIN) often do not support MFA, in these cases an apache configuration like the following could be used with Shibboleth .

<Location /secure>
  Authtype shibboleth
  ShibRequestSetting requireSession On
# Require either MFA or non-swiss user <RequireAny>
# Require MFA <RequireAll> require authnContextClassRef https://refeds.org/profile/mfa require valid-user </RequireAll>
# Require users from non-swiss Identity Provider <RequireAll> <RequireNone> Require shib-attr homeOrganization ~ .*.ch$ </RequireNone> require valid-user </RequireAll>
</RequireAny> </Location>