Questa è la prima volta che configuro OpenID Connect con IdentityServer 4 e AspNetIdentity e speravo che qualcuno potesse demistificare la parte relativa alla memorizzazione dei dati dell'utente.
Quello che ho letto finora è che i dati utente dovrebbero essere archiviati nel db Auth che è connesso al server auth, ma mi piacerebbe davvero archiviare i dati utente anche nel db risorsa che è collegato al server risorse.
Al momento ho un modello di dati che assomiglia a questo:
Ho omesso molti dei campi sia per l'utente che per l'evento, ma spero che tu abbia l'immagine. Abbiamo una tabella utente, una tabella eventi e una tabella host. Un utente può ospitare un evento. La relazione molti-a-molti tra un utente e un evento avviene tramite la tabella host.
Questa è una domanda così rudimentale sull'architettura, ma è davvero difficile trovare una buona risposta che abbia un senso e che non sia un trucco totale. Finora ho letto le seguenti soluzioni da persone diverse:
Memorizzare tutti i dati utente solo nel db Auth e quindi impostare un'API sul server Auth in modo che il server risorse possa ottenere i dati dal server Auth.
Qualcun altro afferma che i dati non relativi all'autorizzazione come la città o il paese di un utente non devono essere archiviati nel db Auth. Conservare invece i dati relativi all'autorizzazione solo nel server Auth e tutti i dati relativi all'utente nel DB delle risorse. Sembra che i due record utente debbano essere sincronizzati? Sembra una cattiva idea.
Avere il server di risorse e il server di autenticazione come un'applicazione in modo da poter costruire le relazioni necessarie tra utente, host ed evento. Ma questo sembra vanificare l'intero scopo dell'utilizzo di OpenID Connect.
Allora, qual è l'architettura standard qui? Oppure, se non esiste una taglia unica, come memorizzeresti questi dati utente?
Con separazione delle preoccupazioni e unica responsabilità in mente:
Non esiste una sola tabella utente. I campi in una tabella hanno solo un significato nel contesto.
Un utente può avere un account Google per accedere, ma per l'azienda che non è l'account in cui è possibile raggiungere il dipendente. E che ne dici di mostrare informazioni su un rapporto che non fa parte del contesto? Supponiamo che memorizzi la città nel contesto dell'identità. Quindi come hai intenzione di mostrare quelle informazioni su un rapporto? Avrai bisogno delle informazioni nel contesto aziendale.
Valuta anche se il contesto dell'identità è un buon posto per archiviare informazioni. Perché l'utente ha il controllo. Cosa succede quando l'utente non fornisce il consenso per l'utilizzo delle informazioni o rimuove semplicemente l'account? E quale strategia usare quando desideri sincronizzare i dati?
La condivisione di contesti è assolutamente no. L'identità è responsabilità di IdentityServer, il contesto dell'identità deve contenere solo informazioni sull'identità ed è accessibile solo da IdentityServer. Si noti che IdentityServer non è associato a un'app.
Avrai bisogno di una tabella utente in ogni contesto. Laddove le informazioni possono sembrare ridondanti ma in realtà non lo sono, perché fanno parte del contesto separato. Come quando accedi utilizzando un provider come Google. Quindi viene creata una copia locale dell'utente nel contesto dell'identità.
Ma forse non dovresti fare riferimento ad esso come Utente nel contesto aziendale. Perché nel contesto aziendale non ci sono utenti. Molto probabilmente sono dipendenti, clienti, ecc. Chi può avere un login, ma non necessariamente. Ed è possibile avere utenti (identitari) che non sono noti all'azienda (ad esempio nel caso di più app).
IdentityServer è l'autorità per autenticare l'utente. L'autorizzazione può essere implementata su più livelli. È possibile creare un server di autorizzazione separato (come policyserver ). O livello inferiore ( basato sulle risorse ), in cui l'esistenza di un utente all'interno della tabella "persona" indica che l'utente ha accesso alla risorsa.
La parte migliore di contesti separati è che all'interno del contesto è possibile creare relazioni tra tabelle, senza interferire con altri contesti. Se lo desideri, puoi facilmente passare a un altro provider OIDC. Ma una volta che inizi a mescolare i contesti, non c'è modo di tornare indietro.
L'unica cosa che è molto utile in oidc è la rivendicazione sub
. Basta cercare l'utente per la rivendicazione sub
e utilizzare l'id locale per il contesto aziendale.
Informazioni sui campi city
e country
nel contesto dell'identità: esistono più livelli di autenticazione, quindi potresti effettivamente avere bisogno delle informazioni in questo contesto. Ma se hai bisogno delle informazioni in un altro contesto (ad es. Per mostrarle sui rapporti), dovrebbero essere aggiunte anche lì ().
Un'opzione aggiuntiva che ho preferito utilizzare personalmente di fronte a un problema simile era semplicemente quella di condividere il database delle identità tra varie applicazioni. Ciò ha risolto il problema della duplicazione non necessaria. Tuttavia, se si procede in questo modo, è necessario provare a garantire che venga mantenuta una sorta di separazione dei problemi: la gestione delle identità non viene eseguita dall'applicazione del server delle risorse e allo stesso modo la gestione dei dati relativi alle risorse non viene eseguita dall'applicazione di autenticazione.