@@ -30,23 +30,25 @@ Dopo aver effettuato l’accesso al sistema, l’utente può controllare e gesti
## 2.1. Installazione del sistema in reti private
Il sistema deve essere installato in reti private senza dover intervenire con configurazioni che riguardino l’apparato di rete.
L'installazione del sistema avviene senza configurazioni particolari: utilizzando mosquitto con la configurazione da noi impostata, è sufficiente collegare il sistema alla rete internet per avere le funzionalità richieste disponibili.
L'installazione del sistema avviene senza configurazioni particolari: utilizzando Mosquitto con la configurazione da noi impostata, è sufficiente collegare il sistema alla rete internet per avere le funzionalità richieste disponibili.
## 2.2. Accessibilità da rete pubblica e da rete privata
Il sistema deve essere accessibile dalla rete pubblica senza differenze rispetto all’accesso da rete interna.
L’uso di brokers mosquitto (in LAN e in Cloud) connessi in bridging garantisce l’accessibilità del sistema sia all'interno della LAN sia al suo esterno.
L’uso di brokers Mosquitto (in LAN e in Cloud) connessi in bridging garantisce l’accessibilità del sistema sia all'interno della LAN sia al suo esterno.
La Webapp, connettendosi a uno di questi broker, permette all'utente di controllare tutti i suoi servizi.
In ogni caso, per accedere al servizio l'utente deve autenticarsi.
Il login è gestito grazie a Keycloak che autorizza l'accesso alla Webapp.
## 2.3. Caratteristiche del traffico dati da sostenere e vincoli in tempo reale
## 2.3. Caratteristiche del traffico dati da sostenere
La quantità di traffico da gestire è appropriata. Le uniche 2 fonti di produzione di messaggi del sistema sono il servizio della BBGPIO, che pubblica a tempo costante di 10s; ed il microservizio dell'antifurto, che pubblica ogni 30s.
La componente umana non è precisamente quantificabile, ma proporzionale nella quantità di messaggi prodotti rispetto al numero di lampadine, sensori e interruttori utilizzati da ogni dominio in un determinato momento.
## 2.4. Vincoli in tempo reale
Essendo un sistema di domotica, è necessario che i comandi impartiti dall'utente vengano attuati una ed una sola volta ed in tempo utile, in modo tale da non inficiare l'esperienza dell'utente che deve risultare al pari o migliore dell'esperienza analogica.
## 2.4. Tecniche viste a lezione con cui soddisfare i requisiti
## 2.5. Tecniche viste a lezione con cui soddisfare i requisiti
Le tecniche viste a lezione sono:
- RPC e API REST
- Message brokers e implementazione di un'architettura event-driven
...
...
@@ -55,7 +57,7 @@ La scelta effettuata è stata quella di usare un message broker.
## 3.1. Vantaggi dell'uso di un message broker
Il message broker risulta fondamentale nello sviluppo di un'applicazione formata da vari microservizi, permettendone la comunicazione. Inoltre facilita la separazione dei problemi della comunicazione dalla business logic del servizio.
L'utilizzo di mosquitto assicura il recapito di ogni messaggio nel numero a noi necessario (impostando il QoS a 2 si riceve uno e un solo messaggio).
L'utilizzo di Mosquitto assicura il recapito di ogni messaggio nel numero a noi necessario (impostando il QoS a 2 si riceve uno e un solo messaggio).
La scelta di utilizzare il protocollo MQTT è dovuta al fatto che è un protocollo molto semplice e leggero, che permette di inviare messaggi in modo veloce e sicuro. Questo protocollo permette di evitare l'invio di messaggi a tutti i microservizi: solo quelli che sono effettivamente interessati al messaggio lo riceveranno.
La centralità del message broker permette la sincronizzazione di tutti i dispositivi ad esso connessi in tempo reale. A differenza dell'utilizzo di RPC, questa soluzione evita lo spreco di risorse causato dal polling dei dispositivi.
...
...
@@ -79,14 +81,14 @@ Il client che esegue nel browser effettuerà chiamate al Webserver per ottenere
Il DM espone un'interfaccia REST, consentendo all'utente che naviga nel browser di effettuare chiamate per installare, avviare, fermare o cancellare domini.
Il CAM, a seguito di chiamate REST da parte del DM, pubblica opportuni messaggi sul mosquitto presente sul cloud, connesso in bridging con il mosquitto presente sulla BB.
Il CAM, a seguito di chiamate REST da parte del DM, pubblica opportuni messaggi sul Mosquitto presente sul cloud, connesso in bridging con il Mosquitto presente sulla BB.
Nella LAN è presente la porzione di sistema che si occupa di comandare le luci, l'antifurto e gli scenari.
Essa è composta da una BB e da un Arduino.
Sulla BB è in esecuzione un broker Mosquitto, a cui si collegano i vari microservizi e il programma in esecuzione sull'Arduino.
Le luci, gli scenari e l'antifurto sono installati sulla BB.
Il Webserver fornisce la Webapp. L'utente, navigando nella Webapp, può controllare e gestire i servizi installati nella LAN.
Il Webserver fornisce la Webapp. L'utente, navigando nella Webapp, può controllare e gestire i servizi installati nella LAN.
## 4.2. Distribuzione delle funzionalità tra i moduli, attività e loro interazione
...
...
@@ -94,31 +96,33 @@ Il Webserver fornisce la Webapp. L'utente, navigando nella Webapp, può controll
### 4.2.1. Keycloak
#### Responsabile: Elisa Giglio
L'autenticazione è gestita con Keycloak. Per ottenere il "grant" di accesso è stata utilizzata la sequenza "Authorization Grant con PKCE".
La pagina iniziale si trova all'url https://localhost:3000/
Per rispondere alla richiesta GET, il Webserver legge la pagina redirect.html e imposta correttamente (in essa) $DOMAIN, $REALM, $MY_REDIRECT_URI in base a quanto scritto nel file kecloak.json (contentente parametri di configurazione di keycloak) e nel file params.json (contenente ulteriori informazioni di keycloak).
La pagina fornita contiene un solo link (non visibile all'utente). Tramite javascript, il client genera un segreto (Code Verifier)
La pagina iniziale si trova all'URL https://localhost:3000/
Per rispondere alla richiesta GET, il Webserver legge la pagina redirect.html e imposta in essa $DOMAIN, $REALM, $MY_REDIRECT_URI in base a quanto scritto nel file kecloak.json (contentente i parametri di configurazione di keycloak) e nel file params.json (contenente ulteriori informazioni di keycloak).
La pagina fornita contiene un solo link (non visibile all'utente). Tramite JavaScript, il client genera un segreto (Code Verifier)
e ne calcola l'hash usando SHA256 (Code Challenge).
Si effettua poi una redirezione della pagina al link specificato, ovvero http://localhost:8080/realms/test00/protocol/openid-connect/auth. In questa richiesta GET sono presenti i seguenti query parameters:
- response_type, settato a 'code';
- code_challenge;
- code_challenge_method, settato a 'S256';
- client_id, settato a 'myclient';
- redirect_uri, settato a 'https://localhost:3000/secured' (questo è l'url registrato presso l'authorization server al quale il browser verrà rediretto nel caso in cui il login vada a buon fine);
- redirect_uri, settato a 'https://localhost:3000/secured' (questo è l'URL registrato presso l'authorization server al quale il browser verrà rediretto nel caso in cui il login vada a buon fine);
- scope, settato a 'openid';
- nonce;
- response_mode, settato a 'fragment';
- state.
Viene quindi mostrata la pagina di login: l'utente inserisce username e password.
Se l'autenticazione ha successo, l'authorization server ridirige il client all'url fornitogli alla precedente richiesta GET (ovvero https://localhost:3000/secured). Nell'url è presente anche 'state' (il cui valore sarà lo stesso inviato nella prima richiesta GET) e 'code' (valorizzato con l'authorization code appena generato dall'authorization server).
Il browser ottiene dal Webserver la pagina domains.html (che è la prima pagina dell'applicazione) e provvede a inviare una richiesta POST all'url http://localhost:8080/realms/test00/protocol/openid-connect/token per ottenere il token. Nel body della richiesta sono specificati i seguenti parametri:
Se l'autenticazione ha successo, l'authorization server ridirige il client all'URL fornitogli alla precedente richiesta GET (ovvero https://localhost:3000/secured). Nell'URL è presente anche 'state' (il cui valore sarà lo stesso inviato nella prima richiesta GET) e 'code' (valorizzato con l'authorization code appena generato dall'authorization server).
Il browser ottiene dal Webserver la pagina domains.html (che è la prima pagina dell'applicazione) e provvede a inviare una richiesta POST all'URL http://localhost:8080/realms/test00/protocol/openid-connect/token per ottenere il token. Nel body della richiesta sono specificati i seguenti parametri:
- grant_type, settato a 'authorization_code';
- client_id, settato a 'myclient';
- code_verifier
- code, valorizzato con l'authentication code ricevuto
- redirect_uri, settato come nella richiesta GET.
A seguito di questa richiesta, l'authorization server rilascia un token e un corrispondente refresh_token (con il quale richiedere un nuovo token).
Periodicamente, prima che scada il token, viene fatta la richiesta di un nuovo token utilizzando il refresh token. In particolare si effettua una POST all'url http://localhost:8080/realms/test00/protocol/openid-connect/token. Nel body della richiesta sono specificati i seguenti parametri:
Periodicamente, prima che scada il token, viene fatta la richiesta di un nuovo token utilizzando il refresh token. In particolare si effettua una POST all'URL http://localhost:8080/realms/test00/protocol/openid-connect/token. Nel body della richiesta sono specificati i seguenti parametri:
- grant_type, settato a 'refresh_token';
- client_id, settato a 'myclient';
- refresh_token.
...
...
@@ -126,9 +130,10 @@ Periodicamente, prima che scada il token, viene fatta la richiesta di un nuovo t
L'accesso alle risorse è consentito solo se si presenta il token. In ogni richiesta inviata al DM è presente l'header 'Authorization' cui è associato il valore 'Bearer ' seguito dal token corrente.
Sia nella pagina contenente la lista dei domini cui l'utente può accedere sia nella pagina di visualizzazione e gestione dei microservizi è presente un bottone per effettuare il logout.
Cliccandolo viene effettuata una richiesta GET all'url http://localhost:8080/realms/test00/protocol/openid-connect/logout. Nell'url sono presenti i seguenti query parameters:
Cliccandolo viene effettuata una richiesta GET all'URL http://localhost:8080/realms/test00/protocol/openid-connect/logout. Nell'URL sono presenti i seguenti query parameters:
- id_token_hint
- post_logout_redirect_uri, settato a 'https://localhost:3000/'
Specificando il parametro id_token_hint, il logout viene effettutato senza che l'utente debba darne una ulteriore conferma.
Il parametro post_logout_redirect_uri consente di effettuare il redirect automatico a https://localhost:3000/ dopo il logout.
...
...
@@ -136,7 +141,7 @@ Il parametro post_logout_redirect_uri consente di effettuare il redirect automat
#### Responsabile: Alfredo Chissotti (Webserver e seconda pagina della Webapp), Elisa Giglio (prima pagina della Webapp)
Il Webserver, implementato come server HTTPS concorrente, fornisce la Webapp al client grazie all'uso di API REST.
La Webapp comunica con il server di autenticazione (Keycloak) ed effettua richieste HTTPS al DM. Nel momento il cui l'utente seleziona un dominio, la Webapp si connette al message broker, mediante il protocollo WSS, consentendo così il controllo e la gestione di tutti i servizi presenti.
La Webapp comunica con il server di autenticazione (Keycloak) ed effettua richieste HTTPS al DM. Nel momento il cui l'utente seleziona un dominio, la Webapp si connette al message broker, mediante il protocollo WSS, consentendo così il controllo e la gestione di tutti i servizi presenti.
### 4.2.3. Domain Manager
#### Responsabile: Alessandro Carbonelli
...
...
@@ -181,24 +186,24 @@ Questo componente della LAN scrive sul broker Mosquitto della BB i valori del se
### 4.2.6 Brokers Mosquitto
#### Responsabile: Elisa Giglio
Il mosquitto che gira sul computer ha 2 listener:
- uno in ascolto sulla porta 8883 che usa il protocollo mqtt,
Il Mosquitto che gira sul computer ha 2 listener:
- uno in ascolto sulla porta 8883 che usa il protocollo MQTT,
- uno in ascolto sulla porta 9001 che usa il protocollo websockets.
Entrambe le porte sono protette con tls.
Entrambe le porte sono protette con TLS.
In particolare, per il listener sulla porta 8883 sono state create una coppia di chiavi e un certificato (caGruppo2.crt) di una Certification Authority (CA) fittizia 'gruppo2Cert'. Dopodichè è stata creata una chiave per il server (serverGruppo2.key), una richiesta (serverGruppo2.csr) per ottenere la firma da parte della CA 'gruppo2Cert' e infine il certificato del server (serverGruppo2.crt) firmato dalla CA 'gruppo2Cert'. Inoltre, poichè 'require_certificate' è settato a 'true', un client che vuole connettersi su questa porta deve inviare il suo certificato.
caWebServer.crt è il certificato della CA 'luci.local' per il listener sulla porta 9001. Come per il listener sulla porta 8883, è stata creata una chiave per il server (server.key), una richiesta (server.csr) per ottenere la firma da parte della CA 'luci.local' e il certificato del server (server.crt) firmato dalla CA 'luci.local'.
Il mosquitto che gira sulla BB ha 3 listener:
- uno in ascolto sulla porta 1883 che usa il protocollo mqtt,
- uno in ascolto sulla porta 8883 che usa il protocollo mqtt,
Il Mosquitto che gira sulla BB ha 3 listener:
- uno in ascolto sulla porta 1883 che usa il protocollo MQTT,
- uno in ascolto sulla porta 8883 che usa il protocollo MQTT,
- uno in ascolto sulla porta 9001 che usa il protocollo websockets.
Le porte 8883 e 9001 sono protette con tls.
Come per il mosquitto sul computer, anche per questi due listener sono stati creati dei certificati.
Le porte 8883 e 9001 sono protette con TLS.
Come per il Mosquitto sul computer, anche per questi due listener sono stati creati dei certificati.
Poichè il microservizio del BBGPIO si connette senza l'uso di certificati, la porta 1883 è stata lasciata aperta.
Il microservizio "Luci" opera in LAN e serve a gestire l'accensione e spegnimento delle lampade nella casa.
La classe principale è Luci.java che, oltre a istanziare il client mqtt, opera su un ArrayList di oggetti di tipo Luce, la struttura dati fondamentale per il funzionamento del microservizio definita dal quartetto input, output, stato e nome.
La classe principale è Luci.java che, oltre a istanziare il client MQTT, opera su un ArrayList di oggetti di tipo Luce, la struttura dati fondamentale per il funzionamento del microservizio definita dal quartetto input, output, stato e nome.
Input è la stringa "IN" seguita dal numero che rappresenta quella sorgente in input della BBGPIO.
Output è la string "OUT" seguita dal numero che rappresenta quello specifico output della BBGPIO.
Stato è un boolean che corrisponde all'accensione o spegnimento della lampadina.
...
...
@@ -295,7 +300,7 @@ In caso di antifurto impostato la classe Timer aggiunge periodicamente un valore
La classe SubscribeCallback gestisce la perdita di connessione con il broker (tentando la riconnessione) e l'arrivo dei messaggi MQTT (in base al messaggio arrivato e al topic su cui è stato pubblicato, viene chiamato un opportuno metodo di questa classe).
La classe Helper espone metodi per la scrittura e la lettura di file.
La classe Helper espone metodi per la scrittura e la lettura di file.
- Scenari
...
...
@@ -354,7 +359,7 @@ Il realm 'test00' ha 4 utenti. Le credenziali degli utenti sono le seguenti:
In questa pagina vengono mostrati tutti i domini appartenenti all'utente autenticato.
Nel caso in cui il dominio sia attivo, un click sul suo nome permette all'utente di visualizzare e gestire i corrispondenti servizi.
Se l'utente è amministratore di un particolare dominio, il bottone dello stato è cliccabile e, in fondo alla riga, è presente un cestino. Un click sul bottone di stato consente di avviare / fermare tutti i microservizi di quel dominio; mentre un click sul cestino elimina l'intero dominio.
Se l'utente è amministratore di un particolare dominio, il bottone dello stato è cliccabile e, in fondo alla riga, è presente un cestino. Un click sul bottone di stato consente di avviare / fermare tutti i microservizi di quel dominio; mentre un click sul cestino elimina l'intero dominio.
Se l'utente non è amministratore di un dominio non potrà agire sul bottone di stato e non vedrà il cestino: potrà solamente accedere al dominio cliccando sul suo nome (se questo è nello stato ON).
In basso a destra è presente un bottone per effettuare il logout dall'intero sistema.