Callback URLs

For device link flows that use a callback URL (Web2App and App2App links), the callback URL handling is very important to achieve a secure and phishing-resistant flow.

Web2App callback URL

For Web2App callback URLs, the following steps must be followed:

  1. The user initiates authentication or signing flow on RP website.

  2. RP website backend has to set a session cookie to the user’s browser. This cookie must be set as SameSite=Lax because later, the Smart-ID app will launch the callback URL using top-level navigation and the request type will be GET.

  3. RP website backend makes a request to RP API and in the initialCallbackUrl, attaches a random parameter as a query parameter which it also saves in the backend and associates it with the session. The objective is for every initialCallbackUrl in any session to be unique and unpredictable.

  4. RP website backend saves the BASE64URL encoded SHA-256 digest of sessionSecret as sessionSecretDigest for later use during verification of the callbackUrl.

  5. Once the user has signed (or rejected the transaction), they are redirected to the callback URL address of RP website and their browser will have the same session cookie. Some aspects to take into account are:

    • User will end up on a new browser tab;

    • The callback URL contains an additional parameter sessionSecretDigest which is the Base64URL encoded SHA-256 digest of the sessionSecret; and in case of authentication flows, it also contains the parameter userChallengeVerifier which is also Base64URL encoded.

  6. RP website sends the callback URL to RP website backend.

  7. RP website backend polls RP API /v3/session/{sessionID} endpoint for the session API response. Note that this can be done before or after the user has returned to the RP website via the callback URL.

  8. RP website backend performs the following checks:

    • Verify that the user’s session cookie matches with the random parameter attached in the callback URL;

    • In authentication flows, verify that after applying the SHA-256 hash algorithm to userChallengeVerifier value (as is, without Base64URL decoding), the result equals to the userChallenge within the signature object sent by the RP API in the session API response;

    • Perform the response verification steps described in Response verification page. Note that this cannot be performed before the user has returned to the RP website via the callback URL;

    • Invalidate the old user session and generate a new one.

IMPORTANT

If any of these steps fail to verify, deny the authentication or signature attempt.

Multiple browser challenges

In cases where user initiated the authentication/signing flow on a mobile browser that was not their default browser, the HTTPS callback URL will probably be opened in the default browser which will not have the session cookie and thus the verification must fail.

App2App callback URL

The protocol steps for handling App2App callback URLs are functionally the same as for Web2App; however, there are also some differences in the steps below due to fundamental differences between webpages and apps.

For App2App callback URLs, the following steps must be followed:

  1. The user initiates authentication or signing flow on RP app.

  2. RP app has to save a session identifier in the app’s storage.

  3. RP app backend makes a request to RP API and in the initialCallbackUrl, attaches a random parameter as a query parameter which it also saves in the backend and associates it with the session. The objective is for every initialCallbackUrl in any session to be unique and unpredictable.

  4. RP app backend saves the BASE64URL encoded SHA-256 digest of sessionSecret as sessionSecretDigest for later use during verification of the callbackUrl.

  5. Once the user has signed (or rejected the transaction), they are redirected to the callback URL, which will cause RP app to open (for this to work, RP app has to be configured to handle that domain and path of the URL).

  6. The callback URL contains an additional parameter sessionSecretDigest which is the Base64URL encoded SHA-256 digest of the sessionSecret; and in case of authentication flows, it also contains the parameter userChallengeVerifier which is also Base64URL encoded.

  7. RP app sends the callback URL together with the session identifier from storage to RP app backend.

  8. RP website backend polls RP API /v3/session/{sessionID} endpoint for the session API response. Note that this can be done before or after the user has returned to the RP website via the callback URL.

  9. RP app backend performs the following checks:

    • Verify that the user’s session identifier matches with the random parameter attached in the callback URL;

    • In authentication flows, verify that after applying the SHA-256 hash algorithm to userChallengeVerifier value (as is, without Base64URL decoding), the result equals to the userChallenge within the signature object sent by the RP API in the session API response;

    • Perform the response verification steps described in Response verification page. Note that this cannot be performed before the user has returned to the RP website via the callback URL;

    • Invalidate the old user session and generate a new one.

IMPORTANT

If any of these steps fail to verify, deny the authentication or signature attempt.

Callback URL examples

If the initial callback URL provided by RP backend is:

https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ

then in the authentication flow the full callback URL would be:

https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ&sessionSecretDigest=U4CKK13H1XFiyBofev9asqrzIrY5_Gszi_nL_zDKkBc&userChallengeVerifier=XtPfaGa8JnGtYrJjboooUf0KfY9sMEHrWFpSQrsUv9c

In the signature and certificate-choice flows the full callback URL would be:

https://rp.example.com/callback-url?value=RrKjjT4aggzu27YBddX1bQ&sessionSecretDigest=U4CKK13H1XFiyBofev9asqrzIrY5_Gszi_nL_zDKkBc

Phishing resistance

For both Web2App and App2App callback URLs, the checks described above provide complete phishing resistance. Always prefer device link flows if possible.

For the response verification steps, see Response verification page.