Dove si inserisce l'autorizzazione in un'architettura a più livelli?


24

In genere, inserisco le decisioni di autorizzazione nei miei controller lato server. Recentemente questi sono stati endpoint RESTful, ma penso che lo stesso stia per architetture di tipo MVC. Per ragioni di argomento, supponiamo che si tratti di un'autorizzazione basata sul ruolo. Un metodo protetto verrà annotato o eseguirà controlli e restituirà 403 se necessario.

Ora, dato che l'autorizzazione è in realtà una regola aziendale - "solo gli amministratori possono elencare X" per esempio, sto pensando che dovrebbero essere spinti giù un livello. Quando un controller chiede al livello aziendale di eseguire l'operazione, il servizio o il livello aziendale informa il controller che non è autorizzato.

È un approccio ragionevole? Ci sono degli svantaggi in questo?

Detesto avere un AuthorisationService che essenzialmente contiene un sacco di regole statiche codificate procedurali per farlo, ma forse ha senso mantenere tutta la logica di accesso in un unico posto. È una preoccupazione trasversale che dovrebbe essere tenuta separata?

Quindi sto chiedendo se qualcuno ha fatto questo e come lo hanno raggiunto in modo pulito o se ci sono buone risorse che potrei leggere. Sto usando Java prima ma questa è una domanda agnostica sul linguaggio.

Ho verificato le domande correlate qui e sono molto sottili sul campo e le risposte. Ad esempio: convalida e autorizzazione nei modelli di dominio e trasporto tramite MVC a un livello di servizio

Sto leggendo i documenti di sicurezza di primavera che sostengono alcune buone argomentazioni perché è una preoccupazione trasversale, ma sono preoccupato che sia solo la "via della primavera" e vorrei prospettive più ampie. Inoltre collega l'applicazione a un framework specifico.


1
Lo stato 403 è errato per problemi di autorizzazione. Usa 401.
gnasher729

@ gnasher729 Penso che sia al contrario. Autenticazione 401 mezzi non è riuscita o non è previsto, 403 mezzi non si dispone di diritti di accesso: stackoverflow.com/questions/3297048/...
JimmyJames

@JimmyJames, c'è un'altra scuola di pensiero che dovresti usare solo una di esse per tutti gli errori di autenticazione e autorizzazione poiché non consente agli strumenti automatizzati di dedurre la logica aziendale con la stessa facilità. C'è qualche margine di manovra.
Berin Loritsch,

1
@BerinLoritsch Spiacente, stai dicendo che l'idea è di rendere più difficile capire se si tratta di un problema di autenticazione o autorizzazione? L'RFC sembra abbastanza chiaro ma afferma che è possibile utilizzare 404 anziché 403 se non si desidera esporre troppe informazioni. C'è un riferimento che puoi fornire per l'argomento per usare un 401 invece di 403?
JimmyJames

@JimmyJames, Sì. Questo processo di pensiero viene da professionisti della sicurezza, non da sviluppatori. E ho anche visto la tua raccomandazione di 404 di nascondere completamente le informazioni per nascondere che la risorsa esiste persino.
Berin Loritsch,

Risposte:


9

È buona norma esporre solo le opzioni per le quali un utente è autorizzato.

Ciò costringe l'autorizzazione a essere una preoccupazione trasversale. La "Vista" deve sapere cosa è autorizzato a fare un utente prima di poter creare opzioni e menu per la visualizzazione.

Il back-end non deve fidarsi del front-end per prendere decisioni sulla sicurezza, quindi deve controllare l'autorizzazione stessa.

Potrebbero esserci delle regole commerciali che incidono sull'autorizzazione in base ai dati, ad esempio "Solo gli utenti con un saldo superiore a $ 5000 possono invocare un trasferimento di valuta estera" o "Solo un utente situato presso la sede centrale può visualizzare questi account". Quindi è necessaria una logica di autorizzazione all'interno della logica aziendale.

Esistono anche autorizzazioni tecniche da considerare: chi è autorizzato a visualizzare i registri, chi può eseguire il backup / ripristinare il database, ecc.

Quindi alla fine ogni componente nel tuo potrebbe avere alcuni requisiti specifici di sicurezza e / o autorizzazione, in pratica è quasi impossibile racchiuderlo in un "livello di autorizzazione" separato.


7

Penso che sia un approccio assolutamente ragionevole per inserire l'autorizzazione nel tuo livello di servizio. È necessario proteggere il servizio dall'esecuzione di attività non autorizzate (in particolare modifiche ai dati). Il tuo livello di servizio potrebbe risiedere in una libreria ed essere utilizzato da diversi livelli di presentazione (potresti avere diverse applicazioni UI che utilizzano lo stesso livello di servizio). E non puoi fare affidamento sul fatto che specifici livelli di Presentazione eseguano la necessaria convalida. Ciò è particolarmente importante se in seguito deciderai di spostare il tuo livello di servizio nel processo separato (ad es. Seguendo l'approccio SOA).

Ora su come raggiungere questo obiettivo in modo "pulito". Non mi piace l'idea di sporcare la logica di business con i controlli di autorizzazione, quindi qualche implementazione specifica di un approccio di programmazione orientato all'aspetto potrebbe aiutare: potrebbe essere decorare metodi di servizio con attributi speciali o usare proxy dinamici con intercettazioni.

E, soprattutto, devo ammettere che, in progetti molto semplici, potresti vivere senza convalide separate, solo per semplificarti la vita. Ma è importante non perdere il momento in cui il "progetto semplice" ha iniziato a diventare "progetto complesso".


7

Mi piace spingere i controlli di autorizzazione più in basso che possono andare! (Ma non oltre!)

Sei ancora libero di scrivere test di autorizzazione automatizzati su livelli "sopra" questo. E alcune regole potrebbero essere applicabili o avere senso solo in livelli superiori come il livello di servizio (CanView / CanSerialize?). Ma, in genere, penso che la strategia di autorizzazione più sicura sia anche la strategia "DRY-est": mantenere le autorizzazioni il più basso possibile, nel codice più "comune" o "condiviso" possibile (senza complicare eccessivamente le regole di autorizzazione).

Pensa all'alternativa. Se le tue regole di autorizzazione vengono testate e applicate solo nel livello di servizio, lasciando che i tuoi oggetti di dominio poveri si pieghino alle volontà degli oggetti di servizio lunatici, ti verrà spesso richiesto di applicare ogni singola regola più di una volta, in più oggetti e più posiziona in ciascun oggetto e in un codice più complicato.

Inoltre, quando il tuo team di analisi assume una società di consulenza per scrivere servizi di reporting utilizzando i tuoi oggetti di dominio, non devi fidarti di quegli sviluppatori! (O qualunque altra cosa. Costruisci servizi aggiuntivi o chiama gli stessi oggetti per qualsiasi motivo.) Non vorrai aprire il grande libro delle regole aziendali e sperare di farle applicare di nuovo correttamente ; vuoi che il tuo dominio li conosca già e li imponga.


@Shoe Se capisco la tua preoccupazione, è questo il punto. Se solo un "amministratore" ha il permesso, secondo le regole aziendali, di creare un Widget, la stessa regola si applica ovunque. (Quindi non rischiare di lasciare che nessuno lo ignori!) Se la regola non si applica ovunque, in realtà non è una regola Widgetse solo Widgets . . Spingere le regole verso il basso fino a quando (le singole regole) possono andare; ma non per quanto riguarda le "regole" ... mi sento come se non stessi affermando bene la distinzione. Ma, ci dovrebbe essere distinzione lì.
svidgen,

Nella mia esperienza, le regole di autorizzazione fanno spesso parte delle regole aziendali. In quanto tale, "fin dove possono andare" è spesso il mio livello di dominio. Ma ho il sospetto che laddove le tue regole "dovrebbero" cadere siano solo una conseguenza del tuo dominio, della natura delle regole e del modo in cui il business ne parla.
svidgen,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.