Sistema di autorizzazione e autenticazione per microservizi e consumatori


15

Abbiamo in programma di trasformare il nostro sistema aziendale in un sistema basato su micro-servizi. Questi micro-servizi saranno utilizzati dalle nostre applicazioni interne aziendali e da partner di terze parti, se necessario. Uno per la prenotazione, uno per i prodotti ecc.

Non siamo sicuri su come gestire ruoli e ambiti. L'idea è quella di creare 3 ruoli utente di base come amministratori, agenti e utenti finali e consentire alle app consumer di mettere a punto gli ambiti, se necessario.

  • Gli amministratori possono creare, aggiornare, leggere ed eliminare tutte le risorse per impostazione predefinita (per la loro azienda).
  • Gli agenti possono creare, aggiornare e leggere i dati per la loro azienda.
  • Gli utenti finali possono creare, aggiornare, eliminare e leggere i dati, ma non possono accedere agli stessi endpoint degli agenti o degli amministratori. Saranno anche in grado di creare o modificare i dati, ma non allo stesso livello degli agenti o degli amministratori. Ad esempio, gli utenti finali possono aggiornare o leggere le informazioni del proprio account, proprio come l'agente sarà in grado di farlo per loro, ma non possono vedere o aggiornare le note dell'amministratore.

Supponiamo che gli agenti di default possano creare, leggere e aggiornare ogni risorsa per la loro azienda e che sia il loro ambito massimo che può essere richiesto per il loro token / sessione, ma gli sviluppatori dell'applicazione client (consumatore API) hanno deciso che uno dei loro agenti può leggi e crea solo determinate risorse.

È una pratica migliore gestire questo nella nostra sicurezza interna e lasciare che scrivano quei dati nel nostro database, o consentire ai clienti di gestirli internamente richiedendo un token con ambito inferiore e lasciare che scrivano quale agente avrà quale ambito nel loro database ? In questo modo dovremmo tracciare solo gli ambiti token.

L'aspetto negativo di questo è che il nostro team dovrebbe anche creare meccanismi di accesso perfezionati nelle nostre applicazioni interne.

Con questo modo di pensare, i micro-servizi e il loro sistema di autorizzazione non dovrebbero essere disturbati dalle esigenze dei clienti, perché sono solo consumatori e non fanno parte del sistema (anche se alcuni di questi consumatori sono le nostre app interne)?

Questa delegazione è un buon approccio?

Risposte:


14

Autenticazione e autorizzazione sono sempre argomenti validi

Proverò a spiegarti come gestiamo le autorizzazioni nell'attuale servizio multi-tenant su cui sto lavorando. L'autenticazione e l'autorizzazione sono basate su token, utilizzando lo standard aperto JSON Web Token. Il servizio espone un'API REST a cui può accedere qualsiasi tipo di client (applicazioni web, mobile e desktop). Quando un utente viene autenticato correttamente, il servizio fornisce un token di accesso che deve essere inviato su ogni richiesta al server.

Consentitemi quindi di introdurre alcuni concetti che utilizziamo in base al modo in cui percepiamo e trattiamo i dati sull'applicazione server.

Risorsa : è qualsiasi unità o gruppo di dati a cui un client può accedere tramite il servizio. A tutte le risorse che vogliamo essere controllate assegniamo un singolo nome. Ad esempio, con le regole dell'endpoint successivo possiamo denominarle come segue:

product

/products
/products/:id

payment

/payments/
/payments/:id

order

/orders
/orders/:id
/orders/:id/products
/orders/:id/products/:id

Quindi diciamo che finora abbiamo tre risorse nel nostro servizio; product, paymentE order.

Azione : è un'operazione che può essere eseguita su una risorsa, come leggere, creare, aggiornare, eliminare, ecc. Non è necessario essere solo le classiche operazioni CRUD, è possibile avere un'azione denominata follow, ad esempio, se si vuole esporre un servizio che propaga qualche tipo di informazione usando WebSocket.

Abilità : la capacità di eseguire un actiona resource. Per esempio; leggere prodotti, creare prodotti, ecc. Fondamentalmente è solo una coppia risorsa / azione. Ma puoi anche aggiungere un nome e una descrizione.

Ruolo : un insieme di abilità che un utente può possedere. Ad esempio, un ruolo Cashierpuò avere le capacità "leggi pagamento", "crea pagamento" o un ruolo Sellerpuò avere le capacità "leggi prodotto", "leggi ordine", "aggiorna ordine", "elimina ordine".

Infine, a un utente possono essere assegnati vari ruoli.


Spiegazione

Come ho detto prima, utilizziamo il token Web JSON e le capacità possedute da un utente sono dichiarate nel payload del token. Quindi, supponiamo di avere un utente con i ruoli di cassiere e venditore allo stesso tempo, per un piccolo negozio al dettaglio. Il payload sarà simile al seguente:

{
    "scopes": {
        "payment": ["read", "create"],
        "order": ["read", "create", "update", "delete"]
    }
}

Come puoi vedere nel scopesreclamo, non specifichiamo il nome dei ruoli (cassiere, venditore), ma vengono specificate solo le risorse e le azioni implicate. Quando un client invia una richiesta a un endpoint, il servizio dovrebbe verificare se il token di accesso contiene la risorsa e l'azione richieste. Ad esempio, una GETrichiesta all'endpoint /payments/88avrà esito positivo, ma una DELETErichiesta allo stesso endpoint deve avere esito negativo.


  • Come raggruppare e nominare le risorse e come definire e denominare le azioni e le abilità sarà una decisione presa dagli sviluppatori.

  • Quali sono i ruoli e quali abilità avranno quei ruoli, sono le decisioni prese dai clienti.


Naturalmente, è necessario aggiungere ulteriori proprietà al payload per identificare l'utente e il cliente (tenant) che ha emesso il token.

{
    "scopes": {
        ...
    },
    "tenant": "acme",
    "user":"coyote"
}

Con questo metodo, è possibile ottimizzare l'accesso di qualsiasi account utente al proprio servizio. E il più importante, non è necessario creare vari ruoli predefiniti e statici, come Admin, Agenti e Utenti finali, come si sottolinea nella domanda. Un Superutente sarà un utente che possiede un rolecon tutto il resourcese actionsdel servizio assegnato ad esso.

Ora, cosa succede se ci sono 100 risorse e vogliamo un ruolo che dia accesso a tutte o quasi tutte? Il nostro payload di token sarebbe enorme. Ciò viene risolto annidando le risorse e aggiungendo semplicemente la risorsa padre nell'ambito del token di accesso.


L'autorizzazione è un argomento complicato che deve essere affrontato in base alle esigenze di ciascuna applicazione.


Grazie per la risposta. Questo è molto utile Ho una domanda relativa a più ruoli per utente. Hai mai avuto un caso in cui le autorizzazioni di ruolo si sovrappongono? Come il cassiere ha payment:[read], il venditore ha payment: [create]. In questo caso aggregate le autorizzazioni?
Robert,

Se hai ruoli con abilità ripetute (resource/action), devi unirli. Se le autorizzazioni si sovrappongono, è necessario aggregarle. L'idea è quella di definire solo le risorse e le azioni consentite nel token, lasciando i ruoli proprio come un'astrazione utilizzata per offrire ai clienti un modo meno complicato di gestire l'autorizzazione.
miso,

1
cosa succede se un utente può solo avere la capacità di agire sulle risorse che PROPRIO. Come ad esempio un conto bancario, sicuramente "bank_account": ["read", "update"] non lo specifica. Inoltre, esattamente DOVE si svolge il processo di autorizzazione in un sistema di microservizi? Su un server di autorizzazione centralizzato o ogni servizio fa la propria autorizzazione?
rocketspacer,

@rocketspacer. Ecco perché il token ha la userproprietà nel suo payload. Il modo in cui blocco una risorsa di proprietà di un utente è mappando il userreclamo sull'URL. Ad esempio: /users/coyote/back-accountsarebbe accessibile solo da un token con userrivendicazione uguale a coyote. Spero che ti aiuti.
miso

3

Penso che, indipendentemente da ciò, vorrai che i tuoi servizi accettino un token di autenticazione fornito da un servizio di autenticazione che scrivi per convalidare gli utenti. Questo è il modo più semplice / sicuro per prevenire l'uso improprio dei microservizi. Inoltre, in generale, se si desidera che un cliente abbia una buona esperienza, è necessario implementare personalmente le funzionalità critiche e testare accuratamente per assicurarsi che le funzionalità offerte siano ben implementate.

Poiché tutti i chiamanti devono fornire la prova dei microservizi che sono stati autenticati, è possibile anche associare le autorizzazioni a tale autenticazione. Se si fornisce la possibilità di legare un utente a un gruppo di accesso arbitrario (o gruppi se si desidera essere fantasiosi, anche se qui è più difficile gestire le autorizzazioni di aggiunta e sottrazione), ci saranno meno domande da parte dei clienti sul perché l'utente x è stato in grado di eseguire un'operazione indesiderata. In ogni caso qualcuno deve fare il controllo della lista di accesso per ogni servizio, quindi potresti anche essere tu. È qualcosa che potrebbe essere facilmente codificato all'inizio di tutti i servizi (if ( !TokenAuthorized(this.ServiceName, this.token) { Raise error }) Che tu possa anche farlo e tenere traccia dei gruppi di utenti da soli. È vero che dovrai avere un gestore di gruppi di autorizzazioni e lavorarlo nell'interfaccia utente di gestione degli utenti (usa esistente / crea un nuovo gruppo per le autorizzazioni degli utenti) Elenca sicuramente gli utenti legati a un gruppo quando modifichi la definizione, per evitare confusione . Ma non è un lavoro duro. È sufficiente disporre di metadati per tutti i servizi e cercare la mappatura tra gruppo e servizio nella gestione dei token di autenticazione.

Ok, quindi ci sono alcuni dettagli, ma ognuno dei tuoi clienti che desiderano questa funzionalità dovrebbe codificarlo in ogni caso, e se supporti le autorizzazioni utente a tre livelli, puoi anche estenderlo in modo che acceda per accesso dell'utente gruppi. Probabilmente un'intersezione logica tra le autorizzazioni del gruppo di base e le autorizzazioni specifiche dell'utente sarebbe la giusta aggregazione, ma se si desidera poter aggiungere e rimuovere le autorizzazioni di base, delle autorizzazioni di base Admin, Agent, Utente finale, è necessario eseguire l'usuale flag tri-state nei gruppi di autorizzazioni: Aggiungi autorizzazione, Nega autorizzazione, Autorizzazione predefinita e combina le autorizzazioni in modo appropriato.

(Come nota, questo dovrebbe succedere su qualcosa come SSL o persino SSL a due vie se sei preoccupato per la sicurezza di entrambe le estremità della conversazione. Se "perdi" questi token a un attaccante, è come se ' d ha violato una password.)


Mentre penso all'infrastruttura e all'implementazione, mi sono completamente dimenticato dell'esperienza del cliente. Mi piace l'idea di creare un insieme di regole che saranno più legate alla nostra attività. Gli amministratori, gli agenti e gli utenti finali sono troppo generici e prevediamo di implementare più tipi di utenti, che sono più descrittivi e legati al nostro linguaggio commerciale e Ubiquitous.
Robert,

Non sono riuscito a correggere l' errore di battitura "anded" nell'ultima frase perché non sono riuscito a capirlo.
Tulains Córdova,

Non è necessariamente un refuso, ma lo renderò più chiaro ..
BenPen,

1

La mia opinione è che tu abbia due scelte qui.

  • Se devi solo avere un accesso configurabile essenzialmente alla stessa applicazione, fai in modo che i servizi controllino le autorizzazioni e forniscano ai tuoi clienti un'interfaccia che permetta loro di cambiare le autorizzazioni assegnate a ciascun ruolo. Ciò consente alla maggior parte degli utenti di utilizzare l'impostazione predefinita del ruolo, che i clienti "problematici" possono modificare i ruoli o crearne di nuovi in ​​base alle proprie esigenze.

  • Se i tuoi clienti stanno sviluppando le proprie applicazioni, dovrebbero presentare le loro API intermedie. Che si collega al tuo come amministratore, ma verifica la richiesta in arrivo rispetto ai propri requisiti di autenticazione personalizzati prima di chiamare i tuoi servizi


1

Considerazione sulla sicurezza

Se capisco bene il tuo progetto, intendi delegare alcuni meccanismi di controllo dell'accesso alle risorse sul lato client, ovvero un'app che consuma riduce gli elementi che un utente può vedere. La tua supposizione è:

i micro-servizi e il loro sistema di autorizzazione non dovrebbero essere disturbati dalle esigenze dei clienti, poiché sono solo consumatori e non fanno parte del sistema

Vedo qui due gravi problemi per le imprese serie:

  • Che cosa succede se un utente canaglia là fuori (ad esempio in uno degli impianti del tuo partner) esegue il reverse engineering dell'app client e scopre l'API, elude le restrizioni che la sua azienda ha posto sul client e utilizza tali informazioni per danneggiare la tua azienda? La tua azienda chiederà il risarcimento dei danni, ma la società partner parlerà che non hai fornito i mezzi per proteggere sufficientemente i tuoi dati.
  • Di solito, è solo questione di tempo in cui i dati sensibili vengono utilizzati in modo improprio (o l'audit scoprirà il rischio) e la direzione finirà per chiedere un controllo più rigoroso di tali dati.

Questo è il motivo per cui consiglierei di anticipare tali eventi e di occuparmi delle richieste di autorizzazione. Sei in una fase iniziale di riprogettazione e sarà molto più semplice tenerne conto nella tua architettura (anche se non le implementerai tutte) che in seguito.

Se persegui la tua posizione attuale, consulta almeno il tuo responsabile della sicurezza delle informazioni.

Come implementarlo

Hai il trucco:

In questo modo, dovremmo tracciare solo gli ambiti token.

Ok, hai intenzione di usare alcuni token generali scelti dal cliente. Ancora una volta una debolezza ai miei occhi, perché alcuni clienti possono essere fuori dal tuo controllo.

Non so se usi già JWT o se usi altre tecniche. Ma se usi JWT, potresti avere un token di identità che porta l'identità dell'utente (e persino un secondo token che identifica in modo sicuro l'app di origine, che potrebbe consentire di differenziare il livello di fiducia tra client interni e client esterni ).

Dato che intendi optare per un'architettura di microservizi, vorrei suggerire di fare la differenza tra la gestione degli utenti e il processo di autenticazione (che dovrebbe essere eseguito come servizio dedicato) e il controllo degli accessi (che è specifico per ciascun microservizio e dovrebbe essere gestito localmente da ciascuno di essi). Ovviamente alcuni client di amministrazione dovrebbero fornire una panoramica completa su più servizi, per facilità d'uso).


1
Ottimo consiglio qui. Mi piace l'idea con il secondo token.
Robert,

1

Anche qui c'è una risposta breve. Dovresti implementare tu stesso tutte le funzionalità di base che desideri offrire ai tuoi "clienti". Sembra problematico che i client aggiungano comportamenti fondamentali come le autorizzazioni degli utenti stessi, dal momento che stai già eseguendo l'autenticazione dell'utente; se lo lasci al client per implementarlo, potresti finire per "supportare" più implementazioni dello stesso codice di autorizzazioni. Anche se non lo "possiedi", ci saranno bug nel loro codice e vuoi che i tuoi clienti abbiano le funzionalità che si aspettavano, entro limiti ragionevoli, quindi supporti la risoluzione dei problemi che un cliente sta riscontrando. Supportare più basi di codice non è divertente.

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.