How to do a "step-up" of the authentication level of a user

In many cases, an application (a “client” in OAuth terms) or an API (an “resource”) has requirements for how the end-user should be authenticated. This includes

  • The security level or assurance level of the authentication.

  • The authentication mechanism, e.g. multi-factor authentication may be a requirement.

  • The identity provider used for authentication. A health-region such as Helse Midt may require that the Helse-Midt IDP is used to authenticate.

  • That the identity of the user authenticated in HelseID is equal to a system-local authentication.

This how-to describes how to determine if a step-up is required, and how to start a new authentication process even though the user is signed in.

Step-up for an application

An application basically have two scenarios where a step-up may be necessary:

  • The application has requirements where a step-up has to be performed

  • The application calls an API (protected by HelseID), and the API responds that a step-up is required (see “Step-up for APIs” further down).

The application has requirements where a step-up has to be performed

After a user sign-in has completed, an application will receive an ID-token from HelseID. This is a JWT signed by HelseID which contains claims (attributes) about the user and the authentication process.

These claims may be used to verify that the authentication satisfy the requirements of the application. Note that you should always verify the signature, issuer, intended audience (your client_id) and validity timestamps of an ID-token before trusting the information in it.

Our claims are specified here, but the following are relevant for determining details about the authentication.

 

Claim

Use

 

Claim

Use

 

idp

Check which IDP was used for authentication

The IDs (“scheme”) of IDPs are available in the public metadata provided by HelseID (test).

amr

The authentication method used in the IDP

Today, this is mapped directly from the information provided by the idp.

auth_time

The time the user was authenticated

As HelseID is a single-sign on service, the auth_time may be up to 10 hours ago - the current session lifetime in HelseID.

helseid://claims/identity/pid

The Norwegian national identifier (“fødselsnummer”) of the end user.

If already you have a local logged user in the application, you should verify that this user is the same as the user signed in in HelseID.

helseid://claims/identity/assurance_level

helseid://claims/identity/security_level

The trust level assigned to an user authentication process

A lot of applications require the highest authentication level (“high”/”4”), but HelseID provides IDPs with lower security levels. You should verify this value if you have such requirements.

 

Doing a step-up

If the application decides that a re-authentication is necessary, it has to redirect the user to HelseID again. Before this is done, it is strongly recommended that the application informs the user why this is done.

The authorization endpoint in HelseID support several parameters which may be used to customize the authentication process. For the full documentation of these parameters, go here.

Parameter

 

Parameter

 

prompt

Set value to login to force a reauthentication

..&prompt=login&...

acr_values

Send the user directly to an IDP supported by HelseID.

..&acr_values=idp:idporten-oidc&...

(Not url-encoded for readability)

 

Step-up for APIs

As of today, there is no standard way for an API to indication to a client that step-up should be performed. However, a proposal for doing this was launched at OSW2021, and is being worked on. It is recommended that new APIs consider using this pattern.

  1. The API should look at the claims in the incoming access token, and determine whether a step-up is necessary. Look at the claims described in “The application has requirements where a step-up has to be performed”.

  2. If a step-up should be performed, the API should:

    1. Return a response code 401 Unauthorized.

    2. Add a http header “WWW-Authenticate”:

      WWW-Authenticate: Bearer error="insufficient_authentication_level", error_description="Security level 'high' is required", acr_values="idp:idporten-oidc Level4"

The acr_values directive is optional, and may be used if the API has specific requirements regarding which IDP should be used.

The Client

If the application receives an 401 from the API, it should check if the WWW-Authenticate header exists and the error directive is set to “insufficient_authentication_level“. If so, a step-up should be performed as described above. If the acr_values parameter is set, this should be forwarded to HelseID.