Docs Testvoorzieningen DigiD proxy

DigiD proxy

You can find the repository on GitLab.

Introduction

This service is used to help projects on Digilab to get started quickly with DigiD implementation. This is only for pre-production purposes, not for production.

Background

Implementing DigiD in software can be time-consuming (both the application process and the technical implementation). To speed up this process for projects that work together with Digilab, this proxy service is made available. Also, the code of this project can help with the actual implementation of DigiD in services.

Demo

See this repo (live demo) for a client that uses this DigiD proxy.

See this repo for an example Flutter app that supports login using DigiD ‘app2app’.

Getting started

  1. Ask the Digilab team to add your client to the config of this proxy. Also provide the URL you want the user to be redirected to after login.
  2. The Digilab team will send you a username-password combination of a user that can be used to login on DigiD.
  3. In your client, add a login button with URL https://saml-preprod.digilab.network/login?state=<identifier of your client, should match the config of this proxy>
  4. When the user is logged in and redirected to your redirect page, a token query parameter with JWT value is set. The identifier (BSN) of the user that has logged in can be found in the sub attribute of the JWT, in the following format: { "subject": "s00000000:111222333" }, where 111222333 is the BSN.
  5. Validate this JWT using the public key found in the sample client repo.
  6. Optionally, add a logout button with URL https://saml-preprod.digilab.network/logout?state=<identifier of your client>

Bonus: steps to implement DigiD

The following is not required for using this DigiD proxy, but in case you want your own dedicated DigiD implementation.

Despite comprehensive documentation from Logius, implementing DigiD can be a bit unclear. The following steps can help to understand the process:

  1. Request a PKIoverheid certificate if your organization does not have one, e.g. via your support department.
  2. Generate your own keypair, e.g. using openssl genpkey -algorithm RSA -out privkey.key and openssl rsa -pubout -in privkey.key -out pubkey.pem.
  3. Apply for a DigiD ‘pre-prod’ integration using this form.
  4. When Logius accepts the application, they will send you a list of 5 test BSNs, for which DigiD usernames and passwords can be entered. After this, these users can be used to log in.
  5. Connect using a SAML library, see the code of this repo as an example.
    • In order to authenticate, a RequestedAuthnContext has to be passed (e.g. allow to log in using username and password only, or with mobile two-factor authentication). See Betrouwbaarheidsniveau in the documentation for more information.
  6. When ‘app2app’ (for mobile apps) is desired, the following additional steps are required:
    1. Create a Google account (for Android) for a specific email address and create an Apple ID (for iOS), preferably for the same email address. Up to three different email addresses can be submitted to Logius for test accounts.
    2. Apply to enable DigiD ‘app2app’ using the wijzigingenformulier. Then apply again using the same form to add the email address(es) as test accounts.
    3. On the Android device or simulator, log in with the Google account created above and install the DigiD PP app from the Google Play store (PP meaning ‘preproductie’). On iOS, get TestFlight from the App Store.
    4. Make sure a phone number is added to the DigiD account you want to activate the app for. A phone number can be added on mijn.preprod1.digid.nl.
    5. Activate the DigiD app on the mobile device or simulator. On Android, ignore messages that a newer version (which refers to the production version of the DigiD app) is available.
    6. Enable opening deep links in the DigiD app, e.g. on Android hold tap on the app icon, then choose App info > Open by default > Open supported links > Switch to on. Then enable the suggested verified link(s).
    7. Also enable deep linking on your mobile app, see this repo for an example in Flutter, see the documentation for how to enable this in the app. Then repeat the step above for the own mobile app to enable verified link(s).
    8. See the code in this repo and the example app for routes to implement the app2app login flow.

Code sample: XML metadata for DigiD application before signing

<?xml version="1.0" encoding="UTF-8"?>
<md:EntityDescriptor
  xmlns:md="urn:oasis:names:tc:SAML:2.0:metadata"
  xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
  xmlns:ec="http://www.w3.org/2001/10/xml-exc-c14n#"
  entityID="https://saml-preprod.digilab.network">
  <md:SPSSODescriptor WantAssertionsSigned="true" AuthnRequestsSigned="true"
    protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
    <md:KeyDescriptor use="signing">
      <ds:KeyInfo>
        <ds:KeyName>Digilab-PKI-overheid</ds:KeyName>
        <ds:X509Data>
          <ds:X509Certificate>base64-encoded value of your public key here</ds:X509Certificate>
        </ds:X509Data>
      </ds:KeyInfo>
    </md:KeyDescriptor>
    <md:AssertionConsumerService
      Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
      Location="https://saml-preprod.digilab.network/saml/sp/artifact_resolution" index="0"/>
  </md:SPSSODescriptor>
</md:EntityDescriptor>

Replace the entityID https://saml-preprod.digilab.network with your own identifier, set your key name, enter the base64-encoded value of the public key you generated, and add the URL of the artifact resolution endpoint you are planning to deploy.

If Eenmalig Inloggen (EI) is desired, some extra metadata is needed, see https://www.logius.nl/domeinen/toegang/digid/documentatie/koppelvlakspecificatie-digid-saml-authenticatie#index-92.

Make sure you sign the metadata with your private key before including it in the DigiD application form, e.g. using the following Python script.

Code sample: script to sign XML metadata

(Make sure the dependencies are installed, e.g. using pip install lxml signxml)

from lxml import etree
from signxml import XMLSigner, XMLVerifier

# Read the original data
data_to_sign = open("samlmetadata.xml", "rb").read()
cert = open("logiuscert.cer").read()
key = open("privkey.key").read()

# Parse the XML
root = etree.fromstring(data_to_sign)

# Sign the XML
signed_root = XMLSigner().sign(root, key=key, cert=cert)

# Convert the signed XML back to a string with pretty print and XML declaration
signed_data = etree.tostring(signed_root, pretty_print=True, xml_declaration=True, encoding='UTF-8')

# Write the signed XML to a file with nice formatting
with open("signed_samlmetadata.xml", "wb") as f:
    f.write(signed_data)

# Optionally, verify the signed XML (for demonstration)
verified_data = XMLVerifier().verify(signed_root, x509_cert=cert).signed_xml