Skip to content

Triggering SPID authentication

Luca Leonardo Scorcia edited this page Aug 9, 2020 · 4 revisions

Triggering a SPID authentication works just like any other IdP login: remote IdPs show up in the Keycloak login screen as buttons on the right side. Now, you can't test authentication with real SPID IdPs before your SP metadata is accepted and distributed by the central federation, but there are a couple of test tools you can use to verify your implementation.

The online SPID Test IdP

You can register an additional IdP in your keycloak setup for the online SPID Test Provider. The IdP metadata document is available at https://idptest.spid.gov.it/metadata and you must register your SP metadata at https://idptest.spid.gov.it/admin/databasesprecord/ before attempting a login. You can find valid credentials and the expected attribute values at https://idptest.spid.gov.it/users.

TIP: The online SPID Test IdP has some kind of funky cache for SP metadata - check twice your document is correct before submitting it. In my tests, every time I had to update the SP metadata I had to delete it from the repository and wait 24 hours, otherwise the new one would not be picked up.

The local SPID TestEnv docker environment

If you need to do a lot of tests, it can be more convenient to setup the SPID TestEnv docker environment (https://github.com/italia/spid-testenv2/). As the name says, it's a Docker environment very similar to the online SPID Test IdP. Some of the checks are different though, so I would recommend testing with both. You will need to register your SP metadata document in its config.yaml file and setup the Identity Provider using its IdP metadata document.

TIP: The metadata and the config.yaml file are only read at container start. If you need to change them during tests, remember to restart the container.

After your tests are over you can just set to Off the Hidden property in the Identity Provider configuration and the test providers won't be available for login anymore.

Complying with the SPID UI Guidelines

There is a precise set of guidelines regarding the display of the SPID IdP buttons (https://github.com/italia/spid-sp-access-button). The best way to create the required UI controls in Keycloak is to edit the login page within a custom theme.

Theming Keycloak is out of the scope of this project, but it's not difficult - please refer to the official documentation. Here I will just mention that you can hide the remote IdP buttons in the default Keycloak UI by setting to ON the Hidden property in the settings of each Identity Provider. They will be enabled but not displayed.

I had very good results by choosing the GET SPID Button template, and implementing each IdP hyperlink like in the following code:

<li class="spid-idp-button-link" data-idp="arubaid">
    <a id="aruba_id" href="#" onclick="return RedirectTo(UpdateQueryString('kc_idp_hint', 'ArubaSpidL2'))"><span class="spid-sr-only">Aruba ID</span><img src="/auth/resources/vysoq/login/mycustomtheme/img/spid-idp-arubaid.svg" onerror="this.src='/auth/resources/vysoq/login/mycustomtheme/img/spid-idp-arubaid.png'; this.onerror=null;" alt="Aruba ID" /></a>
</li>
...
<script type="text/javascript">
  function UpdateQueryString(key, value, url) {
    if (!url) url = window.location.href;
    var re = new RegExp("([?&])" + key + "=.*?(&|#|$)(.*)", "gi"),
        hash;

    if (re.test(url)) {
        if (typeof value !== 'undefined' && value !== null) {
            return url.replace(re, '$1' + key + "=" + value + '$2$3');
        } else {
            hash = url.split('#');
            url = hash[0].replace(re, '$1$3').replace(/(&|\?)$/, '');
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) {
                url += '#' + hash[1];
            }
            return url;
        }
    } else {
        if (typeof value !== 'undefined' && value !== null) {
            var separator = url.indexOf('?') !== -1 ? '&' : '?';
            hash = url.split('#');
            url = hash[0] + separator + key + '=' + value;
            if (typeof hash[1] !== 'undefined' && hash[1] !== null) {
                url += '#' + hash[1];
            }
            return url;
        } else {
            return url;
        }
    }
  }
...
  function RedirectTo(url)
  {
     window.location.href = url;
     return false;
  }
</script>

The key is setting the kc_idp_hint parameter to the Alias value set in the Identity Provider configuration.

That's it, you now have a realm that can successfully authenticate users with SPID and import their data in Keycloak's user store. Still there are a few important open points you should know about before setting up a solution in your Production environment.