Ci sono molte domande qui che trattano i meccanismi di autenticazione e autorizzazione delle API RESTful ma nessuno di loro sembra entrare nei dettagli su come implementare servizi sicuri a livello di applicazione.
Per esempio diciamo che la mia webapp (ho in mente Java, ma questo vale per qualsiasi back-end) ha un sistema di autenticazione sicuro che consente agli utenti dell'API di accedere con un nome utente e una password. Quando l'utente effettua una richiesta, in qualsiasi momento durante la pipeline di elaborazione della richiesta, posso chiamare un metodo getAuthenticatedUser()
che restituirà l'utente null se l'utente non ha effettuato l'accesso o un oggetto dominio utente che rappresenta l'utente connesso .
L'API consente agli utenti autenticati di accedere ai propri dati, ad es. un GET a /api/orders/
restituirà l'elenco di ordini dell'utente. Allo stesso modo, un GET a /api/tasks/{task_id}
restituirà i dati relativi a quell'attività specifica.
Supponiamo che ci siano diversi oggetti di dominio che possono essere associati all'account di un utente (ordini e attività sono due esempi, potremmo anche avere clienti, fatture, ecc.). Vogliamo solo che gli utenti autenticati siano in grado di accedere ai dati relativi ai propri oggetti, quindi quando un utente effettua una chiamata a /api/invoices/{invoice_id}
, è necessario verificare che l'utente sia autorizzato ad accedere a tale risorsa prima di servirla.
La mia domanda è allora, esistono schemi o strategie per affrontare questo problema di autorizzazione? Un'opzione che sto considerando è la creazione di un'interfaccia helper (cioè SecurityUtils.isUserAuthorized(user, object)
), che può essere richiamata durante l'elaborazione della richiesta per garantire che l'utente sia autorizzato a recuperare l'oggetto. Questo non è l'ideale in quanto inquina il codice dell'endpoint dell'applicazione con molte di queste chiamate, ad es.
Object someEndpoint(int objectId) {
if (!SecurityUtils.isUserAuthorized(loggedInUser, objectDAO.get(objectId)) {
throw new UnauthorizedException();
}
...
}
... e poi c'è la questione di implementare questo metodo per ogni tipo di dominio che potrebbe essere un po 'doloroso. Questa potrebbe essere l'unica opzione, ma sarei interessato a sentire i tuoi suggerimenti!