Archive

Archive for the ‘Sicurezza’ Category

Mar
30

Uno degli argomenti di maggiore interesse in un’applicazione, sia essa Web o Enterprise, è sicuramente quello della Sicurezza.

La sicurezza in quanto tale deve essere pensata a tutti i livelli:

  • a livello architetturale: la sicurezza va pensata globalmente. L’applicazione deve essere in grado di difendersi dagli attacchi che il nostro sistema può portarle e deve sapere che attacchi possono arrivare;
  • a livello di codice: ogni singola parte del nostro codice deve partire dal presupposto che i controlli di sicurezza fatti ad un altro livello possano fallire, possano non esserci o possano essere sbagliati;
  • a livello sociologico: l’ultimo ostacolo alla vera sicurezza resta l’impatto che la nostra applicazione avrà sull’utilizzatore finale, quali passi quest’ultimo dovrà intraprendere per far si che la sicurezza venga rispettata e mantenuta. Se i passi e gli sforzi che l’utente dovrà fare sono o troppo difficili o comportano tempi di attesa decisamente non accettabili, allora significa che abbiamo fallito, la sicurezza non verrà rispettata e le falle che si creeranno nella nostra applicazione rischieranno di diventare falle per l’intero sistema ospite, compromettendo, la sicurezza dell’intera infrastruttura;
  • a livello amministrativo: la sicurezza ha un costo anche in termini di manutenzione nel tempo, pensiamo solo al tempo che un amministratore di rete dedica a mantenere aggiornata la struttura di Active Directory che ha in gestione, se l’infrastruttura di sicurezza introdotta dalla nostra applicazione ha un costo di gestione elevato rischiamo che alla lunga venga trascurata perchè troppo onerosa.

Se focalizziamo l’attenzione sugli ultimi due punti ci rendiamo conto che uno dei fattori fondamentali è quello di cercare di rendere la sicurezza il più integrata possibile con il sistema ospite, cercare di renderla il più trasparente possibile a tutti, sia agli amministratori che dovranno gestirla e ancora di più agli utenti finali che dovranno “subirla” come imposizione.

In questa direzione una possibile soluzione è il concetto di “Single Sign On”.

Si parla di sistema basato su “Single Sign On” (SSO) quando le richieste di autenticazione non vengono direttamente gestite dal sistema stesso ma vengono ridirette verso un’altro sistema di autenticazione che ha precedentemente certificato le credenziali dell’utente connesso, senza quindi avere la necessità di richiedere nuovamente le credenziali per l’accesso.

L’obiettivo principe del Single Sign On è proprio quello di rendere la sicurezza trasparente all’utente finale, facilmente manutenibile e gestibile per gli amministratori; l’utente deve rendersi conto di lavorare in un sistema sicuro, ma non deve assolutamente vivere la sicurezza come un onere aggiuntivo.

Una possibile scelta in questo senso è quella di integrare un sistema di “Single Sign On” all’interno delle nostre applicazioni appoggiandoci semplicemente alla gestione degli utenti e gruppi di Windows. In questo modo il nostro sistema si integrerà perfettamente anche con “Active Directory” (con tutti i pregi e difetti del caso che prescindono però dalla trattazione di questo post e che verranno trattati in successivi post).

 

L’architettura

 

Schema DB SSOAbbiamo una tabella “Users” dedicata a contenere i dati relativi agli utenti, una tabella “Roles” che conterrà l’elenco dei ruoli e infine una tabella “RolesRelations” che è dedicata a mantenere le relazioni molti a molti tra gli utenti e i ruoli e, nel caso specifico, tra i ruoli e i ruoli stessi permettendoci di gestire quindi l’inserimento di un ruolo all’interno di un altro ruolo semplificando, in questo modo, di molto la manutenzione nel tempo delle policy di sicurezza dell’applicazione stessa.

Un campo chiave nella base dati è, nella tabella “Users”, il campo “AccountSID”, che  è dedicato a contenere il SID (Security Identifier) dell’utente di Windows o di Active Directory che desideriamo possa accedere alla nostra applicazione. La tabella però non contiene solo un riferimento al SID dell’utente perché è strutturata per permetterci di inserire anche utenti personalizzati che non appartengono al dominio e permetterci quindi di far accedere all’applicazione anche utenti e/o macchine che non fanno direttamente parte della nostra struttura di Active Directory.

 

L’applicazione all’avvio esegue i seguenti passi:

  • recupera il SID dell’utente corrente di Windows, quello cioè della macchina locale su cui è in esecuzione;
  • verifica se il SID, così recuperato, sia presente nella tabella “Users” della nostra base dati:
    • in caso affermativo: Costruisce una GenericIdentity e un GenericPrincipal con le informazioni presenti nella tabella “Users”, assegnando al GenericPrincipal i ruoli corretti sulla base delle relazioni impostate nella tabella “RolesRelations”. Infine assegna il GenericPrincipal ottenuto alla proprietà statica CurrentPrincipal della classe Thread.
    • In caso negativo: Ci limitiamo a mostrare all’utente una bella maschera di richiesta di credenziali e procediamo allo stesso modo, verifichiamo cioè se le credenziali immesse dall’utente, che sappiamo non appartenere al dominio o non essere tra quelli abilitati al “Single Sign On”, siano corrette e in caso affermativo procediamo creando una GenericIdentity e un GenericPrincipal. La verifica viene fatta sempre a fronte dei dati contenuti nella tabella “Users” ma questa volta confrontando la combinazione di Username e Password immessi dall’utente.

Al termine del processo di autenticazione dell’utente sia che il sistema di “Single Sign On” sia entrato in funzione sia che l’utente sia stato autenticato con un processo custom otteniamo lo stesso effetto, abbiamo cioè un GenericPrincipal assegnato al thread corrente e questo ci garantisce che il motore che gestisce la sicurezza all’interno del .NET Framework funzioni come ci aspettiamo.

 

fonti: MSDN Library

 

, ,