Ho 3 progetti di siti web come segue:
- identity.example.com (asp.netcore + IdentityServer4)
- api.example.com (asp.netcore webapi)
- www.example.com (asp.netcore + aurelia)
Sono in grado di autenticare l'utente utilizzando l'agente utente di SPA utilizzando il tipo di concessione implicita e memorizzo access_token su localStorage. Poiché localStorage non è sicuro, access_token di lunga durata o utilizzo di refresh_token non è sicuro, quindi i miei utenti dovranno effettuare il login ogni X minuti, il che non è accettabile come concorderesti.
Il mio obiettivo è lasciare che gli utenti abbiano l'opzione "ricordami di me" e mantenga le cose sicure come accettate (so che non esiste una sicurezza al 100% a questo riguardo)
Penso di avere le seguenti opzioni;
1. Full Proxy tra SPA e API / IdentityServer, tutto memorizzato come cookie http_only
- spa pubblica le credenziali sul proprio back-end (www.esempio.com/login)
- il backend della spa ottiene access_token e refresh_token da identity.example.com, memorizza i token nel cookie http_only o nella sessione.
- il backend della spa funge da proxy tra l'api e la spa e la spa effettua chiamate api al proprio back-end, non all'api
- il backend della spa indirizza tutte le richieste API a api.example.com utilizzando il token_accesso memorizzato nel cookie / sessione e restituisce il risultato a user_agent.
Ora questo approccio sembra sicuro ma aggiunge un livello proxy che avrebbe un effetto negativo sulle prestazioni, richiedere tempi di risposta ecc. Inoltre, avrei bisogno di scrivere un wrapper / proxy per ogni singolo metodo API nel backend della spa (il proxy ) che farebbe chiamate ai metodi di api reali che non è così bello.
Ho pensato al seguente flusso per renderlo sicuro e non doloroso per l'utente allo stesso tempo;
2. Semi Proxy tra SPA e Identity Server (solo per i token di aggiornamento)
Riepilogo: SPA ha accesso a access_token, tuttavia, per aggiornare il token, spa dovrebbe interagire con il suo back-end che mantiene il refresh_token in sessione / cookie in modo sicuro.
-
spa pubblica le credenziali sul proprio back-end (www.example.com/login) - spa ottiene un codice_autorizzazione dal server di identità (client_secret non è necessario per questo) e lo invia al proprio back-end
- il backend della spa ottiene access_token e refresh_token da identity.example.com utilizzando authorization_code, memorizza i token nel cookie http_only o nella sessione e include anche access_token nel corpo della risposta
- la spa memorizza il token di accesso nel suo localStorage e lo utilizza per le chiamate direttamente all'api (api.example.com, senza proxy)
- quando scade il token di accesso, lo user-agent (spa) chiede al proprio back-end di aggiornare access_token per conto di se stesso
- il backend della spa recupera il nuovo access_token e refresh_token dal server di identità. Aggiorna i token nella sessione / cookie e restituisce access_token a user_agent (spa)
-
l'utente_agent (spa) aggiorna il token di accesso nel suo localStorage e lo usa per future chiamate all'api.
Ora, le domande ... L'ultimo flusso che ho descritto è sicuro e accettabile per gli standard? Conoscete un'implementazione di esempio di esso? O hai altri suggerimenti che dovrei seguire? Forse dovrei considerare dei difetti di sicurezza?