Vai al contenuto

Autenticazione

Per poter accedere alle API dedicate ai Registrar è necessario autenticarsi e ottenere un access token utilizzando il protocollo OAUTH2 (RFC6749).

Info

Tutti gli esempi seguenti fanno riferimento al server di autenticazione in produzione auth.nic.it. Per l'ambiente di test (pubtest) utilizzare il server auth.pubtest.nic.it nella stessa identica configurazione.

Il protocollo OAUTH2 prevede diverse modalità di autenticazione (grant_type) per ottenere un access token che variano in funzione del tipo di applicazione che si intende sviluppare. La documentazione seguente fa riferimento all'autenticazione di una applicazione che necessità di utilizzare le API del Registro .it in una modalità server-to-server, ovvero senza l'intervento diretto di un utente che si autentica. Per questi casi è previsto l'uso della modalità di autenticazione denominata client credentials in base alla quale il client stesso (nel nostro caso un client legato a un Registrar) che si autentica e ottiene l'access token.

Per motivi di sicurezza il Registro autentica i client dei Registrar non tramite credenziali (client id e client secret), ma sfruttando un meccanismo di autenticazione basato sull'invio di un JWT firmato (JSON Web Signature JWS - RFC7515 e JSON Web Token JWT - RFC75919). La possibilità di autenticare client con meccanismi diversi dalle credenziali è stata definita da RFC7521 e RFC7523.

Creare un client

Il primo passo da compiere è la creazione di un client. Questa operazione è svolta da un utente del Registrar, appartenente al gruppo admin, attraverso la Gestione Client nel menu Sicurezza disponibile sul portale RAIN. Al termine della creazione del client l'utente potrà scaricare un Keystore in formato PKCS#12 che conterrà la chiave privata da utilizzare per firmare il JWT. Il Keystore sarà protetto da una password scelta dall'utente durante la creazione del client.

La creazione di un client può essere eseguita solo attraverso il portale RAIN e deve essere svolta da un utente con ruolo admin del Registrar. Quando si crea un client è necessario specificare quanto segue:

  • L'utente a cui associare il client, che può essere diverso dall'utente che lo sta creando
  • I gruppi da associare al client. I gruppi disponibili variano in funzione di quelli dell'utente a cui si associa il client. I gruppi determinare quali operazioni sarà possibile eseguire con il client
  • Una data di scadenza del client, oltre il quale non potrà più essere utilizzato. Al momento il massimo della durata è 1 anno

Dopo la creazione del client, solo l'utente a cui è stato associato il client, potrà tramite il portale RAIN, generare il Keystore.

Il seguente grafico riassume i passaggi da compiere per la creazione di un client:

Creare un client

Info

E' importante sottolineare che il Registro non mantiene né il Keystore generato né la password scelta dal Registrar per proteggere il Keystore. Se viene smarrita la password o il keystore, il client deve essere rimosso e ricreato.

Autenticazione con JWT firmato

Una volta creato il client e ottenuto il Keystore, il Registrar potrà autenticarsi e ottenere l'access token che gli permetterà di accedere alle API del Registro.

I passi da compiere per autenticarsi sono descritti nel seguente schema:

Authenticazione

Creare un JWT

La creazione di un JWT può essere fatta sia manualmente che attraverso diverse librerie, generalmente disponibili in ogni linguaggio di programmazione, che ne semplificano la creazione.

Il JWT da creare sarà simile a quello di seguito riportato:

{
    "iss": "7b81d500-62cc-11ed-9b6a-0242ac120002",
    "jti": "8759f4ed-7fbd-40f7-a1ae-1bff576e61ca",
    "sub": "7b81d500-62cc-11ed-9b6a-0242ac120002",
    "aud": [
      "https://auth.nic.it/auth/realms/registrar"
    ],
    "iat": 1739440419,
    "exp": 1739440719
}

I campi presenti nel JWT devono essere compilati seguendo le seguenti regole:

  • iss (issuer) e sub (subject) devono contenere l'identificativo del client (client_id) che sarà generato dal Registro al momento della creazione del client
  • jti (JWT ID) è un identificativo univoco che deve essere diverso per ogni richiesta di autenticazione. Non è possibile autenticarsi più di una volta con il medesimo valore del campo jti (si ottiene altrimenti una risposta con codice HTTP 400 BadRequest). Nell'esempio il campo jti è stato valorizzato con un UUID (Universally Unique IDentifiers - RFC9562)
  • aud (audience) deve contenere la URL relativa al server di autenticazione (https://auth.nic.it/auth/realms/registrar)
  • exp (expiration time), il JWT generato non potrà essere utilizzato per autenticarsi dopo la scadenza indicata in questo campo (tipicamente dovrebbe essere impostata una durata di pochi secondi o minuti)
  • iat (issued at), è l'unico campo facoltativo e serve per indicare il momento in cui è stato emesso il JWT

Firmare un JWT

Una volta creato il JWT con i valori opportuni si deve procedere a firmarlo.

L'operazione di firma prevede che venga estratta la chiave privata dal Keystore per poi procedere alla firma del JWT con la chiave ottenuta. Le gestione del Keystore PKCS#12 e la firma del JWT in genere avviene con librerie o strumenti standard presenti in ogni linguaggio di programmazione.

Autenticazione

Una volta creato il JWT firmato il Registrar può inviarlo al server di autenticazione del Registro e ottenere l'access token necessario per accedere alle API del Registro.

Di seguito è riportato un esempio di richiesta di autenticazione per ottenere un access token (RFC7523):

POST /auth/realms/registrar/protocol/openid-connect/token HTTP/1.1
Accept-Encoding: gzip, deflate
Accept: */*
Connection: keep-alive
Content-Length: 849
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: auth.nic.it

grant_type=client_credentials&client_id=7b81d500-62cc-11ed-9b6a-0242ac120002&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=yJhbGciOiJSUzI1NiJ9.......re5DtY9JJLM_w
curl -X POST https://auth.nic.it/auth/realms/registrar/protocol/openid-connect/token \
    -H "Content-Type: application/x-www-form-urlencoded" \
    -d 'grant_type=client_credentials&client_id=7b81d500-62cc-11ed-9b6a-0242ac120002&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=yJhbGciOiJSUzI1NiJ9.......re5DtY9JJLM_w'
http --form POST https://auth.nic.it/auth/realms/registrar/protocol/openid-connect/token \
    grant_type=client_credentials \
    client_id=7b81d500-62cc-11ed-9b6a-0242ac120002 \
    client_assertion_type=urn:ietf:params:oauth:client-assertion-type:jwt-bearer \
    client_assertion=eyJhbGciOiJSUzI1NiJ9.......re5DtY9JJLM_w

Info

Nell'esempio sopra riportato non è stato specificato alcun scope. Per maggiori informazioni si veda il paragrafo dedicato agli scope.

La risposta alla richiesta di un access token sarà un JSON come il seguente:

Risposta prelevamento Token
{
  "access_token": "eyJhbGciOiJSUzI1NiI....vqnLkImYB-g7HO5yiOtHVFAlaCw",
  "expires_in": 300,
  "refresh_expires_in": 0,
  "token_type": "Bearer",
  "not-before-policy": 0,
  "scope": "registrar"
}

Il campo access_token contiene l'access token che deve essere utilizzato nelle richieste alle API del Registro come nell'esempio seguente:

GET /v1/registrar HTTP/1.1
Authorization: Bearer eyJhbGciOiJSUzI1NiI....vqnLkImYB-g7HO5yiOtHVFAlaCw
Host: api.nic.it
curl -X GET \
     -H "Authorization: Bearer eyJhbGciOiJSUzI1NiI....vqnLkImYB-g7HO5yiOtHVFAlaCw" \
     https://api.nic.it/v1/registrar

Info

L'access token ha una durata limitata, espressa in secondi, indicata nel campo expires_in (nell'esempio la durata è di 300 secondi). Alla scadenza dovrà essere richiesto uno nuovo access token ripetendo i passi descritti sopra.

Gruppi

Durante la creazione di un client è possibile specificare uno o più gruppi a cui appartiene il client. I gruppi limitano le operazioni che possono essere effettuate dal client.

I gruppi al momento utilizzati dalle API sono i seguenti:

  • admin: permette l'accesso a tutte le funzionalità offerte dalle API
  • domain: permette l'accesso alle funzionalità relative ai domini e contatti
  • billing: permette l'accesso alle funzionalità relative ai pagamenti, fatture, credito, ecc.
  • darwin: permette l'accesso, per gli utenti che non sono già nel gruppo admin o domain, alle funzionalità relative a Darwin

Nella documentazione di ogni funzionalità offerta dalle API, è indicato quale gruppo è richiesto per poter usare quella funzionalità.

Scope

Gli scope, definiti nel RFC6749, permettono di specificare lo "scopo" della richiesta di accesso, ovvero indicare o limitare l'uso che si vorrà fare dell'access token ottenuto.

Tip

L'uso degli scope durante l'autenticazione è importante sia per limitare le funzionalità a cui si potrà accedere tramite l'access token ottenuto che per determinare le informazioni (claim) in esso contenute.

Per motivi di sicurezza, si raccomanda di limitare gli scope solo a quelli strettamente necessari.

Nella documentazione di ogni funzionalità offerta dalle API, verrà indicato gli scope che dovranno essere riportati nell'access token per poter usare quella funzionalità.

A titolo di esempio (non esaustivo) sono riportati alcuni degli scope che sono stati creati specificatamente per l'accesso alle API del Registro .it:

  • domain
  • security
  • darwin
  • billing
  • registrar

Note

Alcuni scope, come ad esempio registrar, sono aggiunti di default senza necessità che vengano richiesti

Esistono altri scope non definiti dal Registro che vengono aggiunti in automatico e altri opzionali.

Di seguito un esempio su come richiedere che siano presenti degli scope specifici nel access token:

POST /auth/realms/registrar/protocol/openid-connect/token HTTP/1.1
Content-Type: application/x-www-form-urlencoded; charset=utf-8
Host: auth.nic.it

scope=domain%20security&grant_type=client_credentials&client_id=7b81d500-62cc-11ed-9b6a-0242ac120002&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=yJhbGciOiJSUzI1NiJ9.......re5DtY9JJLM_w
curl -X POST \
     -H 'Content-Type: application/x-www-form-urlencoded' \
     -d "scope=domain%20security&grant_type=client_credentials&client_id=7b81d500-62cc-11ed-9b6a-0242ac120002&client_assertion_type=urn%3Aietf%3Aparams%3Aoauth%3Aclient-assertion-type%3Ajwt-bearer&client_assertion=yJhbGciOiJSUzI1NiJ9.......re5DtY9JJLM_w" \
     https://auth.nic.it/auth/realms/registrar/protocol/openid-connect/token

Nell'esempio sopra riportato sono stati richiesti gli scope domain e security e pertanto potranno essere utilizzate le funzionalità (le API) che richiedono questi valori.

Script di esempio

Per semplificare l'integrazione sono disponibili script di esempio nelle tre modalità supportate:

  • shell POSIX
  • Python
  • Node.js

L'archivio è distribuito insieme alla documentazione e può essere scaricato direttamente da qui: example-scripts.tar.gz.

Dopo aver estratto l'archivio troverai la directory scripts/ con questa struttura:

  • scripts/shell/get-access-token.sh
  • scripts/python/get-access-token.py
  • scripts/python/requirements.txt
  • scripts/nodejs/get-access-token.js
  • scripts/nodejs/package.json

Tutti gli script accettano gli stessi parametri principali:

  • --profile prod|pubtest
  • --keystore /percorso/client.p12
  • --password <password-keystore>
  • --client-id <client-id>
  • --scope 'domain security' opzionale
  • --ttl 300 opzionale
  • --raw-token opzionale, stampa solo il valore di access_token

Utilizzo in shell

Prerequisiti:

  • curl
  • openssl
  • uuidgen

Esempio:

chmod +x ./scripts/shell/get-access-token.sh
./scripts/shell/get-access-token.sh \
  --profile prod \
  --keystore ./client.p12 \
  --password 'secret' \
  --client-id regczyv18nrlqbze6bahw2y1bm5fuhdo3puyksod

Utilizzo in Python

Prerequisiti:

  • python3
  • dipendenze installate da scripts/python/requirements.txt

Installazione dipendenze ed esempio:

python3 -m pip install -r ./scripts/python/requirements.txt
python3 ./scripts/python/get-access-token.py \
  --profile prod \
  --keystore ./client.p12 \
  --password 'secret' \
  --client-id regczyv18nrlqbze6bahw2y1bm5fuhdo3puyksod

Utilizzo in Node.js

Prerequisiti:

  • node
  • dipendenze installate nella directory scripts/nodejs

Installazione dipendenze ed esempio:

npm install --prefix ./scripts/nodejs
node ./scripts/nodejs/get-access-token.js \
  --profile prod \
  --keystore ./client.p12 \
  --password 'secret' \
  --client-id regczyv18nrlqbze6bahw2y1bm5fuhdo3puyksod

Per usare l'ambiente di test è sufficiente sostituire --profile prod con --profile pubtest. Se serve ottenere solo il token da riutilizzare in altri script o pipeline, aggiungere l'opzione --raw-token.