SURFsecureID is SURF's stepup up authentication as a service offering. Institutions can procure this service and let SURF handle step-up authentication to services, including services connected via SURFconext.

For most cases, the Service Provider does not need to change anything or be aware of this. During authentication SURFsecureID is invoked if so configured by the institution and the authentication will proceed as any other. There is one case that does involve the SP. This is where the SP employs the option of dynamically choosing at authentication time which Level of Assurance the user needs to authenticate at. An example is that anyone with only the first factor can log into the service. But in order to perform certain actions, proof of a higher level of assurance is needed.

How it works

Any service provider connected to SURFconext (SAML or OIDC) can ask for a level of assurance as an optional field in the authentication request; no special configuration is needed on the side of SURFconext so you can just start to use it. It is however only useful to do so if the relevant institution(s) use SURFsecureID, otherwise the request will never succeed.

If you just want SURFsecureID with a certain level of assurance enabled for all logins to your service, or all logins from a specific IdP, this option is not for you. This can just be configured on the side of SURFconext and the SP does not need to change anything. You use the option described in this document if you want to use different levels of assurance at different times with the same SP/IdP.

A common use case is to only request the higher level of assurance if the user wants to perform a sensitive action. You let users log into the SP with only the first factor (i.e. not specify anything in particular in the authentication request). Inside the application, when they reach the sensitive action, you start a new authentication request to SURFconext with the higher LoA. Because of Single Sign On, the user will mostly not be asked the first factor again, but will be asked to provide the second factor. After that you receive the authentication back with a statement at which level the user was authenticated.

If any other method of SURFsecureID is configured on the side of SURFconext, the highest level of assurance 'wins'. It is therefore not possible to request a lower level via an AuthnRequest than the minimum level set in other configuration.

Technical implementation

The levels of assurance differ between the SURFconext Test and production environments and take the form of an URL, e.g. http://test.surfconext.nl/assurance/loa2. For more information about the supported Levels of Assurance (LoA), see Levels of Assurance.

You request a LoA at authentication, but it is imperative that you always verify whether it was indeed attained in the returned assertion/token. Your implementation is only secure if you check the received message for the actual level that was used.


SAML 2.0

For SP's connected via SAML 2.0, you specify the LoA URL conform the SAML 2.0 speification in the SAML AuthnRequest in the AuthnContextClassRef element in a RequestedAuthnContext element. All mainstream SAML implementations support this. The request does not need to be signed.

AuthnRequest with a request for authentication at LoA 2
<samlp:AuthnRequest xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
                    xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
                    ID="_ace040cdf97c2efba5aa4d973a32318217b9aaae09"
                    Version="2.0"
                    IssueInstant="2014-05-26T06:47:27Z"
                    Destination="https://engine.test.surfconext.nl/authentication/idp/single-sign-on"
                    >
    <saml:Issuer>http://test-sp.example.com</saml:Issuer>
    <samlp:RequestedAuthnContext>
        <saml:AuthnContextClassRef>http://test.surfconext.nl/assurance/loa2</saml:AuthnContextClassRef>
    </samlp:RequestedAuthnContext>
</samlp:AuthnRequest>

When successful, SURFconext will return a regular assertion in the form it always does for your SP. The AuthnConext element will contain an AuthnContextClassRef with the actual LoA that was presented by the user. Note that this can be higher than the requested minimum. You must check if this value is the same or higher than the one you specified in the request.

Fragment of returned assertion with LoA 3
…
       <saml:AuthnStatement AuthnInstant="2014-05-26T06:47:35Z"
                             SessionIndex="_545581ea-2272-408c-a805-5ada9c18095a"
                             >
            <saml:AuthnContext>
                <saml:AuthnContextClassRef>http://surfconext.nl/assurance/loa3</saml:AuthnContextClassRef>
                <saml:AuthenticatingAuthority>http://idp.example.edu/metadata</saml:AuthenticatingAuthority>
            </saml:AuthnContext>
        </saml:AuthnStatement>
…

OpenID Connect

When using SURFconext via OpenID connect, you request the LoA URL In the acr_values key of the authorization request.

OpenID connect requesting loa2 in acr_values
{
  "acr_values": "http://test.surfconext.nl/assurance/loa2",
  "client_id": "test-sp.example.com",
  "nonce": "example",
  "redirect_uri": "https://test-sp.example.com/redirect",
  "response_mode": "query",
  "response_type": "code",
  "scope": "openid",
  "state": "example"
}

You will find in the ID token the acr claim with the actual LoA that was presented by the user. Note that this can be higher than the requested minimum. You must check if this value is the same or higher than the one you specified in the request.

ID token with acr of LoA 3
{
  "header": {
    "alg": "RS256",
    "kid": "key_2021_06_09_00_00_00_014",
    "typ": "JWT"
  },
  "state": "SIGNED",
  "payload": {
    "acr": "http://test.surfconext.nl/assurance/loa3",
    "aud": "test-sp.example.com",
    "auth_time": 1623235772,
    "exp": 1623242972,
    "iat": 1623235772,
    "iss": "https://connect.test.surfconext.nl",
    "jti": "a53296df-b186-4d1c-97ae-3be7633109f8",
    "nbf": 1623235772,
    "nonce": "example",
    "scope": "openid",
    "sub": "e3105f93605d98c324a29cf61843ea8ec17cc7bc"
  }
}

The SURFconext OIDC Playground has an "ACR values" option where you can experiment with requesting amongst others the SURFsecureID LoA values.

  • No labels