# Integrazione di un servizio di terze parti protetto da autenticazione

Dataset e micro servizi esterni alla piattaforma possono essere facilmente integrati tramite il flusso di autenticazione basato su **JWT** (JSON Web Token) e **JWKS** (JSON Web Key Set)

<figure><img src="https://2402436129-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FNwAiDeLoMPCkkp1BdSbI%2Fuploads%2Fph2eSnbsWYF23XlY9npn%2FSchermata%202024-06-13%20alle%2013.57.11.png?alt=media&#x26;token=f3127994-bc59-4ed9-aa70-353b743c20c9" alt=""><figcaption><p>Diagramma del flusso di autenticazione con JWT e JWKS</p></figcaption></figure>

Questo flusso di autenticazione prevede alcuni passaggi chiave e interazioni tra:

* **client** (browser dell'utente)
* **area personale**
* **micro servizio esterno**

Di seguito il processo punto per punto:

#### **1. Il client richiede il token**

Il client invia una richiesta all'area personale per ottenere un JWT, spesso includendo le credenziali dell'utente o altre forme di autorizzazione.

Come descritto nella sezione [Single Sign-On](https://docs.opencityitalia.it/v/developers/integrazioni/single-sign-on) è possibile per un utente autenticato richiedere un token di autenticazione per la propria sessione.

Questa operazione può essere effettuata facendo una chiamata alle API:&#x20;

{% embed url="<https://servizi.comune.bugliano.pi.it/lang/api/session-auth>" %}
API per ottenere il token JWT come utente loggato
{% endembed %}

oppure come utente non autenticato effettuando  una chiamata POST  alle API

{% embed url="<https://servizi.comune.bugliano.pi.it/lang/api/auth>" %}
API per ottenere il token JWT passando le credenziali
{% endembed %}

```sh
curl --request POST \
  --url https://servizi.comune.bugliano.pi.it/lang/api/auth \
  --header 'Content-Type: application/json' \
  --data '{
	"username": "username",
	"password": "password"
}'
```

#### **2. L'area personale rilascia il token**

L'area personale autentica il client, genera un JWT e lo firma con una chiave privata.

Il token viene quindi restituito al client.

{% code overflow="wrap" %}

```json
{
"token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6InNkYy1xYSJ9.eyJpYXQiO.c2VybmFtZSI6ImFkbWluIiwiaWQiOiI2ZmZkZWRkZi04NmZhLTRjYmEtODUzNC05YTBlNjZmZTNlYmYiLCJ0ZW[...]5hbnRfaWQiOiI2MGUzNWYwMi0xNTA5LTQwOGMtYjEwMS0zYjFhMjgxMDkzMjkifQ.lFe0MR-LAj[...]RjoVvqwk3OX23T642ETu8PUy8sFaVRf1oM1qAnPhLEpnOcrIQY65mpKw6mrJ1rzZM5OVvEeOc4xxmtgcBOfMEBJo_Dw1pMfZHOv2S1S50Zr9XNxk0LcfWjXGdC7wy81eF7UuF-3cX9W"
}
```

{% endcode %}

#### **3. Il client richiede la risorsa al micro servizio esterno:**&#x20;

Il client invia una richiesta al **micro servizio esterno** per accedere a una risorsa protetta, includendo il JWT nell'intestazione Authorization.

{% code overflow="wrap" %}

```sh
curl --request GET \
  --url '{Url API micro servizio esterno}' \
  --header 'Authorization: Bearer {JWT Token}'
```

{% endcode %}

#### **4. Il micro servizio esterno convalida il token**

Per verificare la validità del token il micro servizio esterno **deve:**

* Estrarre il JWT dalla richiesta
* Recuperare il JWKS dall'area personale, il JWKS contiene le chiavi pubbliche necessarie per verificare la firma del JWT.
* Verificare la firma del JWT e convalidare le sue richieste

{% hint style="info" %}
L'area personale espone il JWKS all'indirizzo:\
\
[`https://api.stanzadelcittadino.it/.well-known/jwks.json`](https://api.stanzadelcittadino.it/.well-known/jwks.json)&#x20;
{% endhint %}

#### **5. Accesso concesso/negato**:&#x20;

In base alla validità del JWT il micro servizio esterno concede o nega l'accesso alla risorsa richiesta.

Oltre alla validità del token si possono verificare le affermazioni in esso contenute.

Il payload del token prodotto dall'area personale presenta delle informazioni utili a capire se quello specifico utente oltre ad avere un token valido **ha i permessi** per ottenere la risorsa richiesta.

Di seguito un esempio di payload del token

```json
{
  "iat": 1718278670,
  "exp": 1719142670,
  "roles": [
    "ROLE_CPS_USER",
    "ROLE_USER"
  ],
  "username": "BNRMHL75C06G702B",
  "id": "5b00796e-ef10-4c98-b9f5-b0f7ffd7a17d",
  "tenant_id": "60e35f02-1509-408c-b101-3b1a28109329"
}
```
