Microservizi e autorizzazione

3

Attualmente stiamo lavorando su un sistema basato su micro-servizi. L'idea alla base è dividere il nostro sistema monolitico in piccoli domini (micro-servizio per dominio).

Tutti i servizi saranno utilizzati dalle nostre applicazioni interne, ma abbiamo intenzione di esporlo a pubblico.

Uno dei servizi sarebbe il servizio di gestione delle identità, che sarebbe responsabile per l'emissione e la convalida dei token.

Per i riferimenti condivisi, stiamo usando SharedKernel. Una delle librerie nel kernel condiviso è un AuthorizationAttribute personalizzato, che verrà utilizzato da tutti i micro-servizi. In pratica, ciò che fa l'attributo è l'inoltro del token Bearer al servizio di autorizzazione e il servizio di autorizzazione risponde con informazioni quali la validità del token, le informazioni utente e un set di endpoint / risorse consentiti per il token indicato.

Se l'endpoint corrente non è elencato, viene restituita la risposta HTTP 401.

Ora ho 2 dubbi:

  1. Siamo sulla strada giusta e questo è un approccio valido? In caso contrario, cosa si può fare per migliorarlo?
  2. Abbiamo ancora problemi con il concetto UserTypes / Roles. Probabilmente avremo 3 tipi di utenti. Amministratori, agenti e utenti finali e ancora una volta, se alcune società terze parti decidono di utilizzare la nostra API, i ruoli creati per le nostre esigenze potrebbero non essere adatti alle loro esigenze. Il problema è che non tutti gli agenti avranno impostato le stesse autorizzazioni. Ad esempio potremmo avere un agente che è responsabile della contabilità e che avrebbe accesso solo ai micro-servizi relativi alla contabilità, ma potremmo anche avere un agente che è responsabile solo per la prenotazione. Se questo dovesse richiederci di impostare un UserType per ogni tipo di agente, f. AccountingAgent, BookingAgent ecc. E assegnare più UserTypes all'utente, oppure esiste un approccio più semplice per risolvere questo problema?
posta Robert 18.08.2016 - 13:26
fonte

2 risposte

6

No, non stai utilizzando i token correttamente.

L'idea è che tu abbia un servizio di autorizzazione che emette token e servizi di risorse che possono convalidare il token e leggere le attestazioni in esso contenute. Quindi piuttosto che inoltrare il token al servizio di autenticazione ogni volta che il flusso dovrebbe essere come segue

  • Cliente - > Auth: per favore dammi un token, ecco il mio nome utente e passa
  • Auth - > Cliente: qui c'è un token che ho firmato con la mia chiave privata e contiene il reclamo "sono un agente contabile"

poi

  • Cliente - > Risorsa: ciao, per favore dammi un elenco di account, ecco il mio token
  • Risorsa - > Cliente: ho controllato la firma sul token utilizzando la chiave pubblica dei servizi di autenticazione. quindi so che posso fidarmi della tua affermazione di essere un agente contabile. Ecco l'elenco degli account

poi

  • Cliente - > Risorsa: elimina questo account, ecco il mio token
  • Risorsa - > Client: gli agenti dell'account sorry non sono autorizzati a eliminare account

Questo flusso impedisce al servizio Auth di diventare un collo di bottiglia per le prestazioni e lascia i vari microservizi per decidere se Claim X può fare l'operazione Y

Ruoli

Per indirizzare la tua seconda domanda su ruoli e permessi. Alla fine della giornata un servizio deve avere una serie di ruoli o permessi di cui è a conoscenza. ad esempio, devi codificare qualcosa del tipo:

If(users.Role != "RoleX")
{
    return "Access Denied!";
}

Piuttosto che avere un intero elenco di permessi diversi, "canEditAccounts", "canEditCustomers", "canDeleteAccounts" ... ecc. ecc., l'approccio moderno è invece quello di avere un elenco più breve di AccountingAgent dei ruoli che agisce essenzialmente come un insieme di permessi.

Se una terza parte consuma i tuoi servizi anche se dovranno utilizzare i ruoli che il servizio conosce. Ciò significa che sono bloccati con il livello di granularità che fornisci nei tuoi ruoli.

Ad esempio, se il tuo Accounting Agent fa troppo poco e il tuo Accounting Manager fa troppo per le tue esigenze di terzi, sei bloccato.

Un modo per aggirare questo è avere una mappatura dinamica tra ruoli e permessi. Chiedi al tuo servizio di conoscere le autorizzazioni e interrogare quali autorizzazioni ha un ruolo.

Puoi quindi consentire ai consumatori di terze parti di creare i propri ruoli, selezionando le autorizzazioni che desiderano avere ciascuna

    
risposta data 18.08.2016 - 16:04
fonte
1

Se non hai qualcos'altro come TLS per nascondere il token, renditi conto che se il token viene intercettato, chiunque può usarlo per fingere di essere quell'utente per la durata della sua validità. Personalmente, preferirei qualcosa di simile a un certificato client che non richieda il passaggio di segreti ed elimini la gestione delle sessioni dall'applicazione, ma non c'è nulla di sbagliato nell'approccio token purché tu comprenda e consideri i rischi.

Un vantaggio che vedo per avere un servizio separato che risponde a ciò che l'utente è autorizzato è che può essere sostituito se necessario. Quindi, se una terza parte vuole fare qualcosa di diverso, cambia il comportamento di quel servizio. Puoi semplicemente dire "ecco l'utente X" cosa può fare lui o lei? Questo disaccoppia completamente la struttura di autorizzazione dalle implementazioni del servizio.

L'uso di un servizio separato per gestire le autorizzazioni crea alcune potenziali sfide. Principalmente potrebbe diventare un singolo punto di errore e riceverà una richiesta per ogni chiamata a qualsiasi servizio. Dovresti essere in grado di gestirlo con il ridimensionamento orizzontale durante l'implementazione. È anche possibile incorporare il caching per evitare l'eccessiva chattiness.

    
risposta data 18.08.2016 - 15:48
fonte

Leggi altre domande sui tag