SOA / Microservizi: come gestire l'autorizzazione nelle comunicazioni tra servizi?


18

Primo piano

Stiamo passando da una piattaforma monolitica a un'architettura più orientata ai servizi. Stiamo applicando principi DDD molto basilari e suddividendo il nostro dominio in contesti diversi. Ogni dominio è distribuito ed espone un servizio tramite un'API Web (REST).

A causa della natura della nostra attività, abbiamo servizi come prenotazioni , servizi , clienti , prodotti , ecc.

Abbiamo anche creato un Identity Server (basato su Thinktecture Identity Server 3) il cui ruolo principale è:

  • Centralizza l'autenticazione (date le credenziali che emette i token)
  • Aggiungi reclami nei token come: gli ambiti del client (per client intendo l'applicazione che fa la richiesta), identificativo del cliente (per cliente intendo la persona che utilizza l'applicazione)

Abbiamo anche introdotto il ruolo di un gateway API che centralizza l'accesso esterno ai nostri servizi. API Gateway offre funzionalità che non richiedono una conoscenza approfondita dei domini interni come:

  • Proxy inverso: instrada le richieste in arrivo nel servizio interno appropriato
  • Controllo delle versioni: una versione del gateway API esegue il mapping a diverse versioni dei servizi interni
  • Autenticazione: le richieste client includono il token emesso da Identity Server e il gateway API convalida il token (assicurarsi che l'utente sia chi dice di essere)
  • Limitazione: limitare il numero di richieste per client

Autorizzazione

Ciò che riguarda l'autorizzazione, questo non è gestito nel gateway API ma nei servizi interni stessi. Attualmente stiamo effettuando 2 tipi principali di autorizzazioni:

  • Autorizzazione basata sugli ambiti client. Esempio: un client (applicazione esterna che utilizza le nostre API) richiede l'ambito "bookings" per accedere agli endpoint dell'API del servizio Bookings
  • Autorizzazione basata sul cliente. Esempio: solo se un cliente (persona fisica che utilizza l'applicazione) è un partecipante di una prenotazione può accedere all'endpoint GET / prenotazioni dal servizio Prenotazioni

Per essere in grado di gestire l'autorizzazione nei servizi interni, l'API Gateway inoltra semplicemente il token (quando instrada la richiesta al servizio interno) che include sia le informazioni sul client (l'applicazione che effettua la richiesta) sia il cliente come reclamo (in quei casi in cui una persona è registrata nell'applicazione client).

Descrizione del problema

Fin qui tutto bene fino a quando non abbiamo introdotto la comunicazione interservizi (alcuni servizi possono comunicare con altri servizi per ottenere alcuni dati).

Domanda

Come dovremmo affrontare l'autorizzazione nelle comunicazioni interservizi?

Opzioni considerate

Per discutere le diverse opzioni userò il seguente scenario di esempio:

  • Abbiamo un'applicazione esterna chiamata ExternalApp che accede alla nostra API ( ExternalApp può essere vista come il client ) al fine di creare il flusso di prenotazione
  • ExternalApp necessita dell'accesso al servizio di prenotazioni , quindi garantiamo a ExternalApp l'ambito "prenotazioni"
  • Internamente (questo è qualcosa di completamente trasparente per ExternalApp ) il servizio Prenotazioni accede al servizio Servizi per ottenere i servizi predefiniti di una prenotazione come i voli, le assicurazioni o un noleggio auto

Quando si discute di questo problema internamente, sono comparse diverse opzioni, ma non siamo sicuri quale sia l'opzione migliore:

  1. Quando Bookings comunica con i Servizi , dovrebbe semplicemente inoltrare il token originale che ha ricevuto dal gateway API (indicando che il client è ExternalApp )
    • Implicazioni: potrebbe essere necessario concedere ambiti a ExternalApp che non avrebbero dovuto essere concessi. Esempio: ExternalApp potrebbe aver bisogno di avere sia l'ambito "prenotazioni" che i "servizi" mentre solo l'ambito "prenotazioni" potrebbe essere sufficiente
  2. Quando Bookings comunica con i Servizi , inoltra un token che indica che il client ora è diventato Bookings (invece di ExternalApp ) + aggiunge un reclamo che indica che Bookings sta impersonando il client originale ExternalApp
    • Includendo anche le informazioni che il client originale è ExternalApp, il servizio Servizi potrebbe anche fare una logica come filtrare alcuni servizi a seconda del chiamante originale (ad esempio per le app interne dovremmo restituire tutti i combattimenti, solo per le app esterne)
  3. I servizi non dovrebbero comunicare tra loro (quindi non dovremmo nemmeno essere di fronte a questa domanda)

Grazie in anticipo per il tuo contributo.


1
Come hai risolto questo problema? Siamo in una situazione simile.
Varun Mehta,

+1: Sono interessato a come finalmente risolvi il tuo problema.
Dypso,

Per eseguire il punto 3: i servizi non comunicano tra loro, è necessaria un'interfaccia utente composita. Vedi particular.net/blog/secret-of-better-ui-composition
stevie_c

Risposte:


3

Ti consiglio di avere un canale interno di comunicazione tra i microservizi.

Ad esempio, utilizzare alcuni broker di messaggi come RabbitMQ internamente per inviare / ricevere o pubblicare / sottoscrivere i messaggi tra microservizi.

Quindi il tuo primo utente finale che affronta il servizio "nel tuo esempio il servizio di prenotazione" sarà responsabile della convalida del token e autorizza il cliente a fare questa specifica operazione comunicando con IdentityServer.

Quindi comunicherà con il servizio Servizi tramite il broker dei messaggi e, in tal caso, non è necessario convalidare nuovamente il token.

Immagino che questo modello sarà più semplice e ti offrirà prestazioni migliori.

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.