Vai al contenuto

Autenticazione

Panoramica

SGV GE.CO utilizza meccanismi di autenticazione diversi per modulo, riflettendo l'evoluzione tecnologica del sistema.

Meccanismi per Modulo

GeCo.Alfa / GecoService - Spring Security 3.2

Configurazione: GeCo.Alfa/WebContent/WEB-INF/spring-security.xml

Componenti:

Classe Descrizione
MAutenticationManager Authentication manager personalizzato
MSecurityImpl Implementazione sicurezza
LoginPresenter Presenter per la schermata di login
LoginDao DAO per verifica credenziali

Flusso di autenticazione:

sequenceDiagram
    participant U as Utente
    participant V as Vaadin UI
    participant SS as Spring Security Filter
    participant AM as MAutenticationManager
    participant DB as PostgreSQL

    U->>V: Accesso a /GeCo.Alfa
    V->>SS: DelegatingFilterProxy
    SS->>V: Redirect a login
    U->>V: Username + Password
    V->>AM: authenticate(credentials)
    AM->>DB: Verifica credenziali (ApplicationRealm)
    DB-->>AM: Risultato
    AM-->>V: Authentication token
    V-->>U: Accesso garantito

Dettagli:

  • Filter chain: DelegatingFilterProxy di Spring Security
  • Realm: ApplicationRealm di WildFly
  • Ruoli: Controllo accesso con wildcard (* role)
  • Sessione: Gestita da Vaadin + HTTP session

MobileFineAdapterServer - Spring Boot BASIC Auth

Configurazione: Classe SecurityConfig

Flusso:

  1. Richiesta HTTP con header Authorization: Basic <base64>
  2. Spring Security decodifica credenziali
  3. Verifica su ApplicationRealm di WildFly
  4. Accesso concesso o 401 Unauthorized
GET /mobile/api/tabelleFisse HTTP/1.1
Authorization: Basic dXNlcjpwYXNzd29yZA==

REST (Quarkus) - Multi-Tenant X-Realm

Configurazione: SGVTenantResolver

Il modulo REST non ha autenticazione utente tradizionale, ma implementa isolamento multi-tenant:

  1. Ogni richiesta deve includere header X-Realm: <tenant-name>
  2. SGVTenantResolver risolve il tenant dall'header
  3. Hibernate ORM indirizza al database corretto (isolamento DATABASE-level)
POST /api/verbale/ricerca HTTP/1.1
X-Realm: c_a662
Content-Type: application/json

Errore senza header: 500 - No tenant identifier specified

Moduli WildFly (ElaborazioneService, ConnessioneService, OtticoService, VpnMctcService)

Autenticazione delegata al container WildFly tramite ApplicationRealm. Configurata in:

  • standalone.xml (WildFly configuration)
  • web.xml (security-constraint per modulo)

Keycloak SSO (Pianificato)

L'integrazione Keycloak e pianificata ma non ancora primaria:

  • Stato: In fase di valutazione
  • Obiettivo: Single Sign-On centralizzato per tutti i moduli
  • File: keycloak.json (configurazione client)

Gestione Credenziali

Ambiente Storage Accesso
Sviluppo ~/.m2/settings.xml, Docker .env Locale
Staging HashiCorp Vault / K8s Secrets kubectl get secret
Produzione HashiCorp Vault / K8s Secrets Solo DevOps

Regole:

  • Mai hardcodare credenziali nel codice
  • Mai committare file .env, certificati, chiavi private
  • Credenziali di test: in Bitwarden shared vault o chiedere a DevOps

Password Hashing

Implementazione (CriptPassword.java)

La classe CriptPassword in GeCo.Alfa/src/com/mdatasystem/geco/library/ gestisce l'hashing delle password operatore.

Algoritmo:

public static String criptaPassword(String password, String repartoInseritore)
    throws NoSuchAlgorithmException, UnsupportedEncodingException
{
    // 1. Concatenazione password + salt (codice reparto)
    byte[] input = (password + repartoInseritore).getBytes("UTF-8");

    // 2. SHA-512 singolo passaggio
    MessageDigest digest = MessageDigest.getInstance("SHA-512");
    byte[] hash = digest.digest(input);

    // 3. Output: stringa esadecimale uppercase
    return Hex.encodeHexString(hash).toUpperCase();
}
Parametro Valore Note
Algoritmo SHA-512 512 bit output
Salt Codice reparto (repartoInseritore) Uguale per tutti gli utenti dello stesso reparto
Iterazioni 1 (singolo passaggio) Nessun key stretching
Output Stringa hex uppercase (128 caratteri)
Encoding UTF-8

Limiti di Sicurezza Noti

  • Nessun key stretching: SHA-512 singolo passaggio e vulnerabile a brute-force/rainbow table
  • Salt condiviso: Il codice reparto e lo stesso per tutti gli utenti del reparto
  • Standard moderno: bcrypt, scrypt, o Argon2 con salt unico per utente
  • La migrazione e pianificata ma richiede reset password per tutti gli utenti

Gestione Sessione

Configurazione (web.xml)

Parametro Valore File
Session timeout 31 minuti GeCo.Alfa/WebContent/WEB-INF/web.xml
Heartbeat interval 180 secondi Context parameter in web.xml
Push mode Automatico (async-supported=true) Vaadin server push
Security domain ApplicationDomain jboss-web.xml

Thread-Safety (MSecurityImpl.java)

La classe MSecurityImpl gestisce la sessione utente con locking esplicito su VaadinSession:

// Scrittura thread-safe su sessione Vaadin
public void setSessionVar(String key, Object valore) {
    try {
        VaadinSession.getCurrent().getLockInstance().lock();
        VaadinSession.getCurrent().setAttribute(key, valore);
    } finally {
        VaadinSession.getCurrent().getLockInstance().unlock();
    }
}

Flusso di logout:

  1. Rimozione operatore dalla sessione (ENTITY_USER_SESSION_VAR = null)
  2. Impostazione autenticazione anonima (AnonymousAuthenticationToken con ROLE_ANONYMOUS)
  3. Reset connessione specifica e reparto inseritore

Keycloak Bridge

MSecurityImpl supporta un bridge Keycloak per SSO:

// Flag per bypass validazione Spring Security
private boolean utenteKeycloakValidato = false;

public boolean isUtenteValido() {
    // 1. Se Keycloak ha validato, bypass Spring Security
    if (this.utenteKeycloakValidato) {
        return true;
    }
    // 2. Fallback: validazione Spring Security tradizionale
    Authentication au = SecurityContextHolder.getContext().getAuthentication();
    // ...
}

Integrazione LDAP

Configurazione (spring-security.xml)

GeCo.Alfa supporta autenticazione LDAP opzionale, configurata come bean in spring-security.xml:

Parametro Valore
Classe GecoLDapAutentication
Server 110.0.1.153:1389
Base DN cn=geco,dc=mdatasystem,dc=it
User uid=gecoUser
Admin cn=admin

Credenziali Hardcoded

Le credenziali LDAP sono attualmente hardcoded nel file spring-security.xml. Devono essere esternalizzate in variabili d'ambiente o vault (vedi Threat Model — A05).