5

Sto utilizzando Spring Security Oauth2 come livello di sicurezza nella mia applicazione. Tutto ha funzionato bene finché non sono apparse contemporaneamente chiamate asincrone.Oauth2; Come risolvere il problema con AccessToken scaduto durante più chiamate async asincrone, effettuate contemporaneamente?

Qualcuno può dirmi come gestire il caso successivo:
1. Il client ha un AccessToken che è già scaduto.
2. Il client effettua due chiamate asso asincrone contemporanee alla mia API (ad esempio: Thread1, Thread2).
3. Thread1 riceve un errore: "accessToken expired", prima di Thread2.
4. Utilizzando la Thread di refreshToken1 riceve un nuovo accessToken = qqqqq.
5. Il Thread2 riceve un errore: "access token scaduto", prima di Filettatura1 fa una nuova chiamata al server con il nuovo access token = qqqqq.
6. Usando il refreshToken Thread2 riceve un nuovo access token = wwwww e rimuove l'access token = qqqqq.
7. Qui, il Thread1 effettua una chiamata al server con accessToken = qqqqq che non è attivo.
8. In teoria, è possibile eseguire il loop di entrambi i thread invalidandoli a vicenda.

Io apprezzo tutto l'aiuto, grazie.

risposta

7

Se si ha il controllo sul client, è possibile allegare un numero di versione al token di accesso - se un thread tenta di aggiornare il token di accesso utilizzando un numero di versione precedente viene restituito il token di accesso corrente (recentemente aggiornato) anziché.

public class AccessToken { 
    private int currentVersion; 
    private String accessToken; 

    private static AccessToken currentToken; 

    public static synchronized refresh(AccessToken token) { 
    if(token.currentVersion == currentToken.currentVersion) { 
     AccessToken newToken = // refresh token 
     newToken.currentVersion = currentToken.currentVersion + 1; 
     currentToken = newToken; 
    } 
    return currentToken; 
    } 
} 

Se non si ha alcun controllo sul cliente e/o preferisce risolvere il problema sul lato server, quindi alcune opzioni sono:

  1. consentire al cliente di utilizzare uno token di accesso per thread invece di richiedere loro di condividere un token di accesso globale attraverso i thread.
  2. proibire l'aggiornamento del token di accesso più di una volta ogni, diciamo, 5 secondi. In questo modo, anche se il client esegue un ciclo di aggiornamento, dovrebbero comunque essere in grado di fare progressi.
  3. esporre un metodo che aggiorna solo il gettone se è previsto il token corrente corretta in modo che il cliente possa condizionalmente aggiornare il suo token di accesso (avrai ancora bisogno di esporre il metodo corrente per aggiornare assolutamente il token nel caso in cui i client dimentica il vecchio token di accesso).
+0

La ringrazio molto. Ho il controllo sul client, quindi userò la versione "accessToken". Grazie ancora. –

+0

Il mio Java è arrugginito ma nel codice di esempio c'è ancora una condizione di competizione, giusto? Due thread potrebbero potenzialmente vedere che il token è la versione corrente e quindi provare a eseguire un aggiornamento, con una sovrascrittura indeterminata dell'altro. – JimmidyJoo