Esame di maturità Sistemi e Reti Sessione Ordinaria 2019

📡 Sistemi e Reti · Informatica 2019 — Sessione Ordinaria Intermedio Soluzione completa

Turismo digitale — rete WiFi e POI

Infrastruttura WiFi + BLE per città d’arte, DB relazionale, pagine web PHP, gestione tariffe. Tutti e 4 i quesiti della seconda parte.

Quesiti prima parte: 01 02 03 04
Quesiti seconda parte: I II III IV
Prima Parte
📋
Traccia originale — Ministero dell’Istruzione
Prima e Seconda Parte · Sessione Ordinaria 2019
// testo ufficiale
Riportato per comodità di consultazione.
START
Lettura e Analisi della Traccia
Requisiti · Vincoli · Output richiesti
✓ completato

Scenario

Un Assessorato al Turismo vuole offrire ai visitatori di una città d’arte contenuti multimediali sui POI (Point of Interest) — monumenti, musei, mostre — distribuiti nel centro storico. I contenuti vengono erogati via pagine web su minitablet a noleggio presso InfoPoint (chioschi) dislocati in città.

Formati di pagina

FormatoVideoImmaginiLingua
Base1 min, solo italiano + sottotitoli ENMax 3, didascalia IT/ENItaliano fisso
Avanzata5 min, 1 tra 7 lingue~20, descrizione ~500 car., 1 tra 7 lingueScelta utente

Tre tariffe

TariffaAccesso
BasePagina base per ogni POI
IntermediaPagina avanzata per 3 POI a scelta + base per gli altri
PienaPagina avanzata per tutti i POI

Vincoli progettuali chiave

  • Solo i minitablet forniti dall’InfoPoint possono accedere al servizio
  • Contenuti solo su server (non memorizzati sul dispositivo)
  • Accesso previo password univoca dal biglietto (validità giornaliera)
  • Fruizione solo in prossimità o all’interno del POI di riferimento
  • Restituzione al medesimo InfoPoint (documento d’identità) o a qualsiasi InfoPoint (carta di credito)
// decisioni progettuali chiave
Due sfide centrali: (1) geolocalizzazione — come verificare che il tablet sia davvero dentro/vicino al POI. (2) vincolo dispositivo — come impedire accesso da dispositivi non autorizzati. Entrambe si risolvono con BLE beacon (localizzazione indoor) + certificato client sul tablet (device binding).
01
Quesito 1 — Infrastruttura tecnologica
Architettura · Protocolli · Geolocalizzazione
✓ completato

1a — Architettura di rete e server

L’infrastruttura si articola su tre livelli: server centrale, rete WiFi cittadina e dispositivi client.

Schema topologico — visione generale

// infrastruttura turismo digitale · città d’arte
Topologia infrastruttura turismo POI Server centrale in cima con web app e database, connesso via Internet/fibra alla rete cittadina. InfoPoint (chioschi) collegati al server. Access point WiFi distribuiti ai POI. Minitablet connessi via WiFi con BLE beacon ai POI. Server centrale (Comune / data center) Web App + Auth + Session DB (contenuti + biglietti) Internet / rete fibra comunale InfoPoint 1 InfoPoint 2 AP WiFi + Beacon BLE POI Centrale (es. Duomo) AP WiFi + Beacon BLE POI Museo AP WiFi + Beacon BLE POI Palazzo Storico Minitablet WiFi · GPS · BLE Minitablet WiFi · GPS · BLE Minitablet WiFi · GPS · BLE Rete cablata/fibra AP WiFi + beacon BLE Connessione WiFi dispositivi

Server centrale — caratteristiche e posizionamento

Dove: data center comunale (o hosting cloud della PA con contratto GDPR-compliant). La collocazione municipale garantisce bassa latenza, sicurezza fisica dei dati e governance pubblica dei contenuti culturali.

ComponenteSpecificheMotivazione
Web ServerApache/Nginx + PHP 8.xServe pagine dinamiche con autenticazione sessione
Media ServerVideo streaming (HLS) dedicatoI video 5 min in 7 lingue richiedono banda elevata; separare da web server migliora le prestazioni
DB ServerMySQL/MariaDB o PostgreSQLDati strutturati: biglietti, POI, contenuti, sessioni
Auth ServiceSession manager (Redis)Sessioni rapide in memoria per validazione password biglietto
CDN localeCache video/immagini su infrastruttura WiFiRiduce latenza per file pesanti (TAC 200 MB), evita colli di bottiglia
// scelta architetturale
Il media server separato dal web server è una scelta architetturale chiave: con centinaia di visitatori simultanei che guardano video HLS, un unico server si saturerebbe. Il CDN locale (cache presso gli AP) riduce ulteriormente il traffico verso il server centrale per i contenuti più popolari.

1b — Protocolli e servizi di comunicazione

LivelloProtocollo / ServizioFunzione
WiFiIEEE 802.11ac (WiFi 5) o 802.11ax (WiFi 6)Connettività wireless dei minitablet; banda sufficiente per streaming video 5 min
Sicurezza WiFiWPA2-Enterprise (802.1X) con certificato sul tabletSolo dispositivi con certificato valido accedono alla SSID del servizio
IPDHCP privato (192.168.x.0/24 per zona)Assegnazione automatica IP ai tablet
ApplicativoHTTPS (TLS 1.3)Comunicazione cifrata tra tablet e server; mandatory per dati di autenticazione
SessioneCookie di sessione sicuro (HTTPOnly, Secure, SameSite=Strict)Mantiene l’autenticazione dopo il login con password biglietto
VideoHLS (HTTP Live Streaming) su HTTPSStreaming adattivo; il tablet richiede chunk di video man mano
Gestione reteRADIUS (802.1X) + DHCP + DNS localeAutenticazione WiFi centralizzata; risoluzione nomi interna
MonitoringSNMP v3 / SyslogMonitoraggio AP e switch; log centralizzati

1c — Geolocalizzazione: accesso solo in prossimità del POI

È il vincolo tecnicamente più critico. Tre opzioni a confronto:

TecnologiaPrecisioneIndoorCostoScelta
GPS3–5 m outdoorNO (segnale assente)Basso (integrato nel tablet)Solo fallback outdoor
BLE Beacon1–5 m indoor/outdoorBasso (beacon €5–20 cad.)✓ Scelta principale
WiFi RSSI3–10 mParzialeZero (usa AP esistenti)Fallback secondario
QR CodeDipende dall’utenteMinimoNo (falsificabile)

Soluzione adottata: BLE beacon + GPS come fallback

Ad ogni POI vengono installati uno o più beacon BLE (Bluetooth Low Energy, protocollo iBeacon/Eddystone). Il tablet scansiona in background le trasmissioni BLE. Ogni beacon ha un UUID univoco associato al POI nel database. Il flusso è:

  1. Il tablet rileva il beacon BLE del POI e invia l’UUID al server via HTTPS
  2. Il server verifica: questo UUID corrisponde al POI richiesto? Il biglietto è valido e autorizza questo POI?
  3. Solo se entrambe le verifiche passano, la pagina multimediale viene servita
  4. Il server registra l’accesso (timestamp + POI + biglietto) per audit
// perché BLE e non solo GPS
I POI più rilevanti (musei, chiese, palazzi storici) si trovano in aree urbane dense con segnale GPS debole e soprattutto all’interno degli edifici dove il GPS non funziona. I beacon BLE funzionano perfettamente indoor, hanno autonomia 2–4 anni a batteria, e la verifica UUID lato server impedisce la simulazione del segnale (il tablet non può “simulare” di rilevare un beacon che non c’è fisicamente nelle vicinanze).
02
Quesito 2 — Database
Modello concettuale (ER) · Modello logico relazionale
✓ completato

Entità e relazioni — Modello Concettuale (ER)

// schema ER — turismo POI · entità principali
Schema ER database turismo POI Entità: Infopoint, Visitatore, Biglietto, POI, Contenuto, Immagine. Relazioni: Visitatore compra Biglietto, Visitatore registrato a Infopoint, Biglietto autorizza POI (per tariffa intermedia), POI ha Contenuto, POI ha Immagini. INFOPOINT PK id_infopoint nome, indirizzo telefono VISITATORE PK id_visitatore tipo_doc, num_doc FK id_infopoint data_registrazione BIGLIETTO PK id_biglietto password (hash) tipo_tariffa data_emissione FK id_visitatore POI PK id_poi nome, tipo indirizzo coord_lat, coord_lon beacon_uuid SCELTA_POI FK id_biglietto FK id_poi, lingua (solo tariffa intermedia) 1:N 1:N N:M

Modello logico relazionale

Schema relazionale — DDL MySQL
CREATE TABLE INFOPOINT ( id_infopoint INT PRIMARY KEY AUTO_INCREMENT, nome VARCHAR(100) NOT NULL, indirizzo VARCHAR(200), telefono VARCHAR(20) );CREATE TABLE VISITATORE ( id_visitatore INT PRIMARY KEY AUTO_INCREMENT, tipo_doc ENUM(‘documento’,’carta_credito’) NOT NULL, num_doc VARCHAR(100) NOT NULL, — hash se carta di credito id_infopoint INT NOT NULL, data_reg DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (id_infopoint) REFERENCES INFOPOINT(id_infopoint) );CREATE TABLE BIGLIETTO ( id_biglietto INT PRIMARY KEY AUTO_INCREMENT, password_hash VARCHAR(255) NOT NULL, — bcrypt hash tipo_tariffa ENUM(‘base’,’intermedia’,’piena’) NOT NULL, data_emissione DATE NOT NULL, — validità giornaliera id_visitatore INT NOT NULL, FOREIGN KEY (id_visitatore) REFERENCES VISITATORE(id_visitatore) );CREATE TABLE POI ( id_poi INT PRIMARY KEY AUTO_INCREMENT, nome VARCHAR(150) NOT NULL, tipo ENUM(‘monumentale’,’artistico’) NOT NULL, indirizzo VARCHAR(200), coord_lat DECIMAL(10,7), coord_lon DECIMAL(10,7), beacon_uuid VARCHAR(36) UNIQUE — UUID beacon BLE univoco );CREATE TABLE CONTENUTO ( id_contenuto INT PRIMARY KEY AUTO_INCREMENT, id_poi INT NOT NULL, tipo_pagina ENUM(‘base’,’avanzata’) NOT NULL, lingua CHAR(2) NOT NULL, — IT EN FR DE ES PT ZH url_video VARCHAR(500), durata_min TINYINT, — 1 o 5 FOREIGN KEY (id_poi) REFERENCES POI(id_poi), UNIQUE (id_poi, tipo_pagina, lingua) );CREATE TABLE IMMAGINE ( id_immagine INT PRIMARY KEY AUTO_INCREMENT, id_poi INT NOT NULL, url VARCHAR(500) NOT NULL, didascalia_it VARCHAR(500), didascalia_en VARCHAR(500), ordine TINYINT DEFAULT 0, — ordinamento galleria FOREIGN KEY (id_poi) REFERENCES POI(id_poi) );— Tabella di associazione per tariffe intermedia/piena: traccia le scelte POI CREATE TABLE SCELTA_POI ( id_biglietto INT NOT NULL, id_poi INT NOT NULL, lingua CHAR(2) NOT NULL DEFAULT ‘IT’, PRIMARY KEY (id_biglietto, id_poi), FOREIGN KEY (id_biglietto) REFERENCES BIGLIETTO(id_biglietto), FOREIGN KEY (id_poi) REFERENCES POI(id_poi) );
// nota su password_hash
La password del biglietto va memorizzata come hash bcrypt (NON in chiaro). Al momento del login il server esegue password_verify($input, $hash) per validare senza mai ricostruire la password originale. La validità giornaliera viene controllata confrontando data_emissione con la data corrente.
03
Quesito 3 — Pagine web per tariffa base
Progettazione · Codice PHP/HTML · Logica sessione
✓ completato

Flusso di navigazione — tariffa base

  1. Login: visitatore inserisce la password del biglietto → server verifica hash + validità data → crea sessione PHP
  2. Elenco POI: lista di tutti i POI disponibili (pagina base garantita a tutti)
  3. Selezione POI: il tablet invia UUID beacon rilevato + id_poi richiesto
  4. Verifica prossimità: server controlla che beacon_uuid del tablet corrisponda al beacon_uuid del POI nel DB
  5. Erogazione contenuto: serve pagina base con video (1 min, IT) + fino a 3 immagini

Pagina login (login.php)

login.php — autenticazione con password biglietto
<?php session_start(); require_once ‘db.php’;if ($_SERVER[‘REQUEST_METHOD’] === ‘POST’) { $pwd_input = trim($_POST[‘password’]); $oggi = date(‘Y-m-d’);// Cerca biglietti emessi oggi (validità giornaliera) $stmt = $pdo->prepare( “SELECT id_biglietto, password_hash, tipo_tariffa FROM BIGLIETTO WHERE data_emissione = ?” ); $stmt->execute([$oggi]); $biglietto = null;foreach ($stmt->fetchAll() as $row) { if (password_verify($pwd_input, $row[‘password_hash’])) { $biglietto = $row; break; } }if ($biglietto) { $_SESSION[‘id_biglietto’] = $biglietto[‘id_biglietto’]; $_SESSION[‘tipo_tariffa’] = $biglietto[‘tipo_tariffa’]; $_SESSION[‘data_login’] = $oggi; header(‘Location: poi_list.php’); } else { $errore = ‘Password non valida o biglietto scaduto.’; } } ?> <!DOCTYPE html> <html lang="it"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Accesso — Turismo Città</title> <!– CSS omesso per brevità –> </head><body> <?php if (isset($errore)) echo “<p class=’error’>$errore</p>”; ?> <form method=“post” action=“login.php”> <input type=“password” name=“password” placeholder=“Password del biglietto” required> <button type=“submit”>Accedi</button> </form> </body></html>

Pagina contenuto POI — tariffa base (poi_base.php)

poi_base.php — fruizione pagina multimediale di base
<?php session_start(); require_once ‘db.php’;// 1. Verifica sessione attiva e validità giornaliera if (!isset($_SESSION[‘id_biglietto’]) || $_SESSION[‘data_login’] !== date(‘Y-m-d’)) { header(‘Location: login.php’); exit; }$id_poi = intval($_GET[‘poi’] ?? 0); $beacon_uuid = trim($_GET[‘beacon’] ?? );// 2. Verifica prossimità: il beacon rilevato corrisponde al POI richiesto? $stmt = $pdo->prepare( “SELECT id_poi, nome FROM POI WHERE id_poi = ? AND beacon_uuid = ?” ); $stmt->execute([$id_poi, $beacon_uuid]); $poi = $stmt->fetch();if (!$poi) { http_response_code(403); die(‘<h2>Accesso non consentito: non sei vicino a questo POI.</h2>’); }// 3. Recupera contenuto base (lingua IT, 1 min) $stmt = $pdo->prepare( “SELECT url_video FROM CONTENUTO WHERE id_poi = ? AND tipo_pagina = ‘base’ AND lingua = ‘IT'” ); $stmt->execute([$id_poi]); $contenuto = $stmt->fetch();// 4. Recupera immagini (max 3) $stmt = $pdo->prepare( “SELECT url, didascalia_it FROM IMMAGINE WHERE id_poi = ? ORDER BY ordine LIMIT 3” ); $stmt->execute([$id_poi]); $immagini = $stmt->fetchAll(); ?> <!DOCTYPE html> <html lang="it"><head> <meta charset="UTF-8"> <title><?= htmlspecialchars($poi[‘nome’]) ?></title> </head><body> <h1><?= htmlspecialchars($poi[‘nome’]) ?></h1><!– VIDEO HLS 1 minuto –> <?php if ($contenuto): ?> <video controls width=“100%” poster=“thumb.jpg”> <source src=“<?= htmlspecialchars($contenuto[‘url_video’]) ?>” type=“application/x-mpegURL”> </video> <?php endif; ?><!– GALLERIA immagini (max 3) –> <div class="gallery"> <?php foreach ($immagini as $img): ?> <figure> <img src=“<?= htmlspecialchars($img[‘url’]) ?>” alt=“<?= htmlspecialchars($img[‘didascalia_it’]) ?>” loading=“lazy”> <figcaption><?= htmlspecialchars($img[‘didascalia_it’]) ?></figcaption> </figure> <?php endforeach; ?> </div> </body></html>
// nota sicurezza
Tutti i dati interpolati nell’HTML vengono passati per htmlspecialchars() per prevenire XSS. Le query al DB usano prepared statements per prevenire SQL injection. L’UUID beacon viene fornito dal tablet tramite JS (Web Bluetooth API) e validato server-side: il server è l’unica fonte di autorità.
04
Quesito 4 — Gestione tariffe e opzioni utente
3 tariffe · Scelta 3 POI · Scelta lingua
✓ completato

Logica server-side per le tre tariffe

La tariffa è memorizzata nella sessione al momento del login ($_SESSION['tipo_tariffa']). Ad ogni richiesta di pagina POI, il server esegue la funzione di autorizzazione:

auth_contenuto.php — logica autorizzazione tariffe
<?php /** * Determina il tipo di pagina autorizzata per un biglietto su un dato POI. * Restituisce ‘avanzata’ o ‘base’. */ function getTipoPagina(PDO $pdo, int $id_biglietto, int $id_poi): string {// Recupera tariffa del biglietto $stmt = $pdo->prepare(“SELECT tipo_tariffa FROM BIGLIETTO WHERE id_biglietto = ?”); $stmt->execute([$id_biglietto]); $tariffa = $stmt->fetchColumn();if ($tariffa === ‘piena’) { return ‘avanzata’; // sempre avanzata per tutti i POI }if ($tariffa === ‘intermedia’) { // Controlla se questo POI è tra i 3 scelti $stmt = $pdo->prepare( “SELECT COUNT(*) FROM SCELTA_POI WHERE id_biglietto = ? AND id_poi = ?” ); $stmt->execute([$id_biglietto, $id_poi]); if ($stmt->fetchColumn() > 0) { return ‘avanzata’; } }return ‘base’; // tariffa base o POI non scelto in tariffa intermedia } ?>

Scelta dei 3 POI (tariffa intermedia)

Al primo accesso con tariffa intermedia, il visitatore vede un form di selezione. Il server verifica che non abbia già esaurito le 3 scelte disponibili prima di registrarne una nuova:

Selezione POI avanzato — frammento PHP
<?php // Conta le scelte già effettuate $stmt = $pdo->prepare( “SELECT COUNT(*) FROM SCELTA_POI WHERE id_biglietto = ?” ); $stmt->execute([$id_biglietto]); $scelte_usate = (int) $stmt->fetchColumn(); $MAX_SCELTE = 3;if ($_SERVER[‘REQUEST_METHOD’] === ‘POST’ && $scelte_usate < $MAX_SCELTE) { $id_poi_scelto = intval($_POST[‘id_poi’]); $lingua = strtoupper(substr(trim($_POST[‘lingua’]), 0, 2));// Inserisce la scelta (IGNORE evita duplicati) $stmt = $pdo->prepare( “INSERT IGNORE INTO SCELTA_POI (id_biglietto, id_poi, lingua) VALUES (?, ?, ?)” ); $stmt->execute([$id_biglietto, $id_poi_scelto, $lingua]); $scelte_usate++; }// Recupera la lingua scelta per questo POI (se già in SCELTA_POI) $stmt = $pdo->prepare( “SELECT lingua FROM SCELTA_POI WHERE id_biglietto = ? AND id_poi = ?” ); $stmt->execute([$id_biglietto, $id_poi]); $lingua_poi = $stmt->fetchColumn() ?: ‘IT’; ?>

Scelta della lingua (tariffe intermedia e piena)

La lingua è selezionabile al momento dell’accesso al POI avanzato. Viene salvata in SCELTA_POI.lingua per la tariffa intermedia (legata alla scelta specifica del POI), oppure in $_SESSION['lingua'] per la tariffa piena (impostazione globale modificabile in qualsiasi momento dal menu).

TariffaLingua per POI baseLingua per POI avanzatoDove si salva
BaseIT (fisso, no scelta)— (non disponibile)
IntermediaIT (fisso)1 delle 7, scelta al 1° accesso a quel POISCELTA_POI.lingua per POI scelto
PienaIT (fisso)1 delle 7, modificabile da menu globale$_SESSION[‘lingua’]
// motivazione design
Salvare la lingua in SCELTA_POI per la tariffa intermedia — e non solo in sessione — garantisce che il visitatore non possa cambiare lingua su un POI avanzato già “consumato”: la scelta linguistica è legata alla scelta del POI, non alla sessione corrente.
Seconda Parte
I
Quesito I — Commenti e voti di gradimento
Estensione DB · Pagina media voti per POI
✓ completato

Estensione del database

Si aggiunge la tabella RECENSIONE. Il vincolo di chiave esterna su id_biglietto garantisce che solo visitatori con biglietto valido possano recensire.

DDL — tabella RECENSIONE
CREATE TABLE RECENSIONE ( id_recensione INT PRIMARY KEY AUTO_INCREMENT, id_poi INT NOT NULL, id_biglietto INT NOT NULL, voto TINYINT NOT NULL CHECK (voto BETWEEN 1 AND 5), commento TEXT, timestamp_ins DATETIME DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (id_poi) REFERENCES POI(id_poi), FOREIGN KEY (id_biglietto) REFERENCES BIGLIETTO(id_biglietto), UNIQUE (id_poi, id_biglietto) — una recensione per POI per biglietto );

Pagina web — media voti per POI

media_voti.php — visualizzazione media gradimento POI
<?php require_once ‘db.php’;// Query: media voti e numero recensioni per ogni POI (solo quelli con almeno 1 voto) $sql = “SELECT p.id_poi, p.nome, p.tipo, ROUND(AVG(r.voto), 1) AS media_voto, COUNT(r.id_recensione) AS num_recensioni FROM POI p LEFT JOIN RECENSIONE r ON p.id_poi = r.id_poi GROUP BY p.id_poi, p.nome, p.tipo ORDER BY media_voto DESC NULLS LAST”;$risultati = $pdo->query($sql)->fetchAll(); ?> <!DOCTYPE html> <html lang="it"><head> <meta charset="UTF-8"> <title>Gradimento POI</title> </head><body> <h1>Media voti — Punti di interesse</h1> <table border="1"> <tr> <th>POI</th><th>Tipo</th><th>Media voto (1–5)</th><th>Recensioni</th> </tr> <?php foreach ($risultati as $r): ?> <tr> <td><?= htmlspecialchars($r[‘nome’]) ?></td> <td><?= htmlspecialchars($r[‘tipo’]) ?></td> <td><?= $r[‘media_voto’] ?? ‘N/D’ ?> <?php if ($r[‘media_voto’]): ?> <span><?= str_repeat(‘★’, round($r[‘media_voto’])) . str_repeat(‘☆’, 5 – round($r[‘media_voto’])) ?></span> <?php endif; ?> </td> <td><?= $r[‘num_recensioni’] ?></td> </tr> <?php endforeach; ?> </table> </body></html>
// nota SQL
La clausola NULLS LAST ordina correttamente i POI senza recensioni in fondo (MySQL usa ORDER BY media_voto IS NULL, media_voto DESC). LEFT JOIN garantisce che compaiano anche i POI senza nessuna recensione.
II
Quesito II — Dispositivi: solo minitablet vs smartphone personale
Device binding · Accesso da dispositivi personali
✓ completato

Ipotesi A — Solo minitablet dell’InfoPoint

Per impedire l’accesso da dispositivi non autorizzati si combinano più livelli:

#MeccanismoCome funzionaLimitazioni
1Certificato client TLSOgni minitablet ha un certificato X.509 univoco emesso dall’InfoPoint. Il server HTTPS richiede client certificate authentication (mutual TLS). Senza certificato, la connessione è rifiutata a livello TLS.Necessita CA interna; complessità di gestione certificati
2WiFi WPA2-Enterprise (802.1X)Ogni tablet ha identità RADIUS univoca. Solo i tablet registrati si connettono alla rete del servizio. Smartphone personali non ottengono IP.Il visitatore non può usare la propria rete dati (4G)
3Device fingerprint + UUID dispositivoAl momento della consegna, l’InfoPoint registra nel DB l’identificativo hardware del tablet (Android ID / numero seriale). Il server verifica ad ogni richiesta che il device ID in sessione corrisponda a quello registrato.Il device ID potrebbe essere falsificato su dispositivi rooted
4MAC address whitelist (a livello AP)Il controller WiFi ammette solo i MAC dei tablet pre-registrati. Efficace a livello di rete locale, ma non sostituisce la verifica applicativa.MAC spoofing possibile
// soluzione consigliata (livello 1+3)
Il certificato client mTLS è la soluzione più robusta: non dipende dalla rete WiFi (funziona anche se il visitatore usa la propria connessione 4G) e non è falsificabile senza la chiave privata che è memorizzata nel keystore sicuro del tablet. Il device fingerprint aggiunge un secondo livello applicativo. I due meccanismi si completano.

Ipotesi B — Estensione a dispositivi personali (smartphone)

Per aprire il servizio ai dispositivi personali mantenendo i vincoli di tariffa:

  1. App mobile dedicata (iOS/Android): scaricabile dall’app store, distribuita dall’Assessorato. L’app gestisce il Bluetooth per rilevare i beacon BLE e la comunicazione con il server.
  2. Autenticazione con password biglietto: stessa logica dell’ipotesi A — la password valida per 24h crea un JWT (JSON Web Token) con scadenza giornaliera.
  3. JWT per sessione stateless: il server emette un JWT firmato con la tariffa e i POI scelti embedded. L’app invia il JWT ad ogni richiesta. Il server verifica firma e scadenza senza accedere al DB.
  4. Vincolo geolocalizzazione: l’app usa Web Bluetooth (o nativo Bluetooth LE) per rilevare il beacon del POI. Il UUID del beacon viene incluso nel payload della richiesta e verificato server-side — identico all’ipotesi con minitablet.
  5. Anti-abuso: un biglietto è legato a un solo device_id per sessione (al primo login, il server associa il JWT al device_id dello smartphone). Tentativi di login da device_id diversi entro la stessa giornata richiedono ri-autenticazione all’InfoPoint.
// differenza chiave
L’apertura ai dispositivi personali elimina il vincolo di rete (WiFi dedicato) e la necessità di certificati hardware — ma richiede il download dell’app, il che rappresenta una frizione per il turista occasionale. Una soluzione ibrida (PWA — Progressive Web App) abbassa questa frizione: il sito funziona come app senza installazione, usando la Web Bluetooth API per i beacon BLE.
III
Quesito III — Sicurezza DB e gestione utenze DBMS
GRANT / REVOKE · Ruoli · Esempio segreteria scolastica
✓ completato

Modello di controllo accessi nei DBMS — RBAC

I sistemi DBMS (MySQL, PostgreSQL, Oracle) implementano il controllo degli accessi tramite DAC (Discretionary Access Control) con il modello RBAC (Role-Based Access Control). Si assegnano privilegi a ruoli, poi i ruoli agli utenti: modificare le autorizzazioni di un ruolo si propaga automaticamente a tutti gli utenti che lo ricoprono.

I privilegi elementari nei DBMS SQL sono: SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, EXECUTE (per stored procedure), GRANT OPTION (per delegare).

Esempio: database scolastico

Schema ipotetico: tabelle ALUNNI, DOCENTI, FORNITORI, VOTI, STIPENDI.

MySQL — creazione utenti, ruoli e assegnazione privilegi
— ═══════════════════════════════════════════════════ — 1. Creazione ruoli (MySQL 8.0+ / MariaDB 10.0.5+) — ═══════════════════════════════════════════════════ CREATE ROLE ‘segr_alunni’; CREATE ROLE ‘segr_docenti’; CREATE ROLE ‘direzione’; CREATE ROLE ‘amministrazione’;— ═══════════════════════════════════════════════════ — 2. Assegnazione privilegi ai ruoli — ═══════════════════════════════════════════════════— Segreteria Alunni: gestisce iscrizioni, voti, assenze — MA non accede ai dati del personale docente GRANT SELECT, INSERT, UPDATE, DELETE ON scuola.ALUNNI TO ‘segr_alunni’; GRANT SELECT, INSERT, UPDATE ON scuola.VOTI TO ‘segr_alunni’; GRANT SELECT ON scuola.DOCENTI TO ‘segr_alunni’; — solo lettura (per assegnare classi) — NESSUN accesso a STIPENDI, FORNITORI— Segreteria Docenti: gestisce contratti e turni docenti — MA non accede all’elenco fornitori né ai dati degli alunni GRANT SELECT, INSERT, UPDATE, DELETE ON scuola.DOCENTI TO ‘segr_docenti’; GRANT SELECT, INSERT, UPDATE ON scuola.STIPENDI TO ‘segr_docenti’; — NESSUN accesso a ALUNNI, VOTI, FORNITORI— Direzione: lettura su tutto, nessun accesso a STIPENDI dettaglio GRANT SELECT ON scuola.ALUNNI TO ‘direzione’; GRANT SELECT ON scuola.DOCENTI TO ‘direzione’; GRANT SELECT ON scuola.VOTI TO ‘direzione’; GRANT SELECT ON scuola.FORNITORI TO ‘direzione’; — Accesso aggregato a stipendi (non nominale): tramite VIEW CREATE VIEW scuola.V_STIPENDI_AGGREGATI AS SELECT tipo_contratto, AVG(importo) AS media, COUNT(*) AS n FROM scuola.STIPENDI GROUP BY tipo_contratto; GRANT SELECT ON scuola.V_STIPENDI_AGGREGATI TO ‘direzione’;— Amministrazione: accesso completo (DBA) GRANT ALL PRIVILEGES ON scuola.* TO ‘amministrazione’;— ═══════════════════════════════════════════════════ — 3. Creazione utenti fisici e assegnazione ruoli — ═══════════════════════════════════════════════════ CREATE USER ‘mario.rossi’@‘%’ IDENTIFIED BY ‘P@ssw0rd!’; GRANT ‘segr_alunni’ TO ‘mario.rossi’@‘%’; SET DEFAULT ROLE ‘segr_alunni’ TO ‘mario.rossi’@‘%’;CREATE USER ‘anna.bianchi’@‘%’ IDENTIFIED BY ‘S3cur3#pw’; GRANT ‘segr_docenti’ TO ‘anna.bianchi’@‘%’; SET DEFAULT ROLE ‘segr_docenti’ TO ‘anna.bianchi’@‘%’;— Revoca privilegio: rimossa la possibilità di cancellare voti a segr_alunni REVOKE DELETE ON scuola.VOTI FROM ‘segr_alunni’;— Verifica privilegi utente SHOW GRANTS FOR ‘mario.rossi’@‘%’;
// VIEW come filtro su dati sensibili
La VIEW V_STIPENDI_AGGREGATI mostra solo medie per tipo contratto — non i singoli importi nominali. Concedere accesso a una VIEW anziché alla tabella è il pattern standard per esporre dati aggregati a ruoli che non devono vedere i dettagli individuali (privacy). Questo pattern si chiama column-level security tramite VIEW.
IV
Quesito IV — VPN e accesso remoto
Tipologie · Protocolli · Due sedi + agenti commerciali
✓ completato

Tipologie di accesso remoto

TipoProtocolloCaso d’usoAutenticazione
Accesso diretto (RDP/SSH)RDP (3389), SSH (22)Gestione singolo server remotoUsername + password / chiave pubblica
VPN client-to-site (roadwarrior)OpenVPN, IPSec IKEv2, WireGuard, SSL/TLSUtente mobile → rete aziendaleCertificato + password / MFA
VPN site-to-siteIPSec tunnel mode, GRE+IPSec, SD-WANDue sedi fisse sempre connessePSK o certificati tra gateway
SSL VPN (browser-based)HTTPS (443)Accesso applicazioni specifiche senza client VPNLDAP/SAML/MFA

Scenario: azienda con 2 sedi + agenti commerciali

// VPN aziendale · site-to-site + roadwarrior
Schema VPN aziendale: sede principale, sede secondaria, agenti remoti Sede principale con server e VPN gateway a sinistra, tunnel IPSec site-to-site verso sede secondaria a destra, agenti commerciali (roadwarrior) in basso che si collegano tramite OpenVPN/IKEv2 alla sede principale. Sede principale (Milano) Server aziendale (ERP, CRM) VPN Gateway (IPSec + OpenVPN) LAN: 192.168.1.0/24 IP pub: 203.0.113.1 IPSec AES-256 tunnel Sede secondaria (Roma) PC e stampanti ufficio VPN Gateway LAN: 192.168.2.0/24 IP pub: 198.51.100.1 Agente 1 OpenVPN client Agente 2 IKEv2 / IPSec Agente 3 SSL VPN browser

VPN site-to-site (2 sedi)

Le due sedi rimangono sempre connesse tramite un tunnel IPSec in modalità tunnel. I router/firewall di entrambe le sedi stabiliscono il tunnel automaticamente all’avvio:

  • IKE Phase 1 (ISAKMP SA): negoziazione algoritmi (AES-256, SHA-256, DH group 14), autenticazione tramite certificati X.509
  • IKE Phase 2 (IPSec SA): definizione del traffico da cifrare (tutto tra 192.168.1.0/24 e 192.168.2.0/24), cifratura ESP-AES-256-HMAC-SHA256
  • I PC della sede Roma vedono i server di Milano come se fossero sulla stessa LAN

VPN Remote Access (agenti commerciali)

Gli agenti si connettono da qualsiasi rete (4G, WiFi hotel) alla VPN gateway della sede principale:

// differenza fondamentale site-to-site vs roadwarrior
Nel site-to-site i gateway parlano tra loro automaticamente: gli utenti finali non sanno di usare una VPN. Nel roadwarrior ogni agente ha un client VPN che deve connettersi esplicitamente. Il site-to-site è trasparente e permanente; il roadwarrior è esplicito e on-demand.

Lascia un commento