Trattare la sicurezza come una preoccupazione separata e gestirla in un livello sopra la logica dell'applicazione è una buona pratica.
Un progetto a cui ho partecipato è stato un ottimo esempio. Ha coinvolto una famiglia di servizi web. L'evoluzione del nostro controllo dell'autorizzazione è andata così (è un po 'Java-centric, ma si spera che l'idea sia chiara):
- In primo luogo come un vaso condiviso in bundle in tutti i servizi.
Tuttavia, come abbiamo ottimizzato la logica di sicurezza, ci ha costretti a ricostruire e ridistribuire tutto. Yuck.
- Avanti un jar condiviso che ha implementato un filtro JEE, in bundle con tutti i servizi.
Questo era meglio, ma qualsiasi modifica ci ha ancora richiesto di ricostruire & ridistribuire tutto.
- Successivamente come filtro Tomcat che abbiamo implementato con Tomcat, al di fuori del file .war
Meglio ancora. Ma i nostri ritocchi richiedevano ancora una distribuzione e amp; riavvio dei server Tomcat.
- Finalmente un proxy inverso che si comportava come un proprio servizio separato dagli altri servizi, che prendevano tutte le richieste e inoltrava le richieste valide inoltrate al server giusto, oppure restituiva un errore "non autorizzato".
E questo ha funzionato come un incantesimo, perché la modifica dei problemi di autorizzazione richiedeva solo una ricostruzione e la ridistribuzione di un servizio: il proxy inverso.
Quindi, vedi, in quel caso abbiamo finito per estorcere del tutto la sicurezza verso l'alto e fuori dal servizio.
Sono d'accordo con la tua sensazione che spingere la sicurezza più in alto nello stack di chiamate come un gate rende la logica di implementazione molto più pulita e più facile da gestire. Se si combinano la logica dell'applicazione con i controlli di sicurezza, c'è il rischio di fare un lavoro extra prima di scoprire (whoops) che non sono autorizzati a fare il passaggio 3. O peggio, potrebbe essere una situazione di rollback in cui l'app deve effettivamente disfare cosa ha fatto nel passaggio 2.
È utile considerare la sicurezza come un livello separato, indipendentemente dal fatto che quel livello sia in codice, un filtro servlet o un proxy upstream. Anche se la sicurezza è una lista di acquisti di azioni, determinare cosa vogliono fare in anticipo e quindi convalidare che sono autorizzati a fare tutto ciò prima che inizi il lavoro effettivo. Ciò fornisce una separazione davvero importante delle preoccupazioni.
...
Un'altra pratica che ho trovato che semplifica notevolmente i problemi di sicurezza sta legando le regole di sicurezza a "ruoli" o "ambiti". Dite freddo, il cliente X vuole fare operazioni X, Y and Z
, e questo richiede scope M and P
. Una rapida ricerca (possibilmente in cache) risponde rapidamente se le operazioni che vogliono fare sono coperte dagli ambiti che hanno.
Quanto ampia o granulare gli ambiti è solo una domanda di progettazione, ma consente di essere ampia o granulare, se necessario.