2014-12-05 12 views
12

Attualmente sto implementando una funzione di password dimenticata in un progetto Java. la mia metodologia è,Implementazione della funzionalità di password dimenticata in Java

  1. L'utente fa clic sul collegamento password dimenticata.
  2. Nella pagina Password dimenticata, il sistema richiede all'utente di inserire l'indirizzo e-mail che ha registrato nel sistema.
  3. Un'e-mail che contiene un collegamento per reimpostare la password viene inviata all'indirizzo e-mail indicato nel passaggio precedente.
  4. L'utente fa clic sul collegamento e viene reindirizzato a una pagina (reimpostazione della password) in cui l'utente può immettere la sua nuova password.
  5. Nella pagina Reimposta password, il campo "indirizzo e-mail" viene compilato automaticamente e non può essere modificato.
  6. Quindi l'utente immette la sua nuova password e il campo relativo all'indirizzo di posta elettronica nel database viene aggiornato.

Anche se ho ristretto il campo email address nella pagina di reset della password dalla modifica (un campo di sola lettura) uno può alterare l'URL nella barra degli indirizzi del browser e modificare il campo indirizzo di posta elettronica.

Come si limita ogni utente a modificare l'indirizzo di posta elettronica nella pagina di reimpostazione della password?

+0

Eventuali duplicati di [Hai dimenticato: qual è il metodo migliore per l'implementazione di una funzione password dimenticato] (https://stackoverflow.com/questions/522967/forgot-password-what-is-the-best-method-of-implementing-a-forgot-password-funct) – OhadR

risposta

30

dovete salvarlo in DB prima di inviare e-mail utilizzando token:

  1. Quando l'utente clicca su "mi mandi una mail con le istruzioni di reset", si crea un record nel DB con quei campi: email, token, expirationdate
  2. utente ricevere e-mail con yourwwebsite.com/token e fare clic su di esso
  3. con la token nell'URL, server può identify the user, controllare se la richiesta non è scaduto, grazie a ExpirationDate, mettere email corretto nella scatola, e chiedere passwo rinnovo. L'utente digita le nuove password e devi fornire il token (hidden field nel modulo) + le password al server. Al server non interessa la casella di testo dell'e-mail perché with the token, user is identified strongly
  4. Quindi il server controlla se il token è ancora valido con expirationdate (di nuovo), controlla se password match e se tutto è ok, salva nuova password! Il server può inviare nuovamente un messaggio per informare l'utente che la password è stata cambiata a causa della richiesta.

Questo è veramente sicuro. Si prega di utilizzare breve tempo per il rafforzamento della sicurezza (ad esempio 5 minuti è corretto per me) e utilizzare token forte (come GUID, vedere commenti)

+1

Ma l'utente può comunque modificare il token nel barra degli indirizzi. – vigamage

+2

@ user3892439 Ma senza conoscere un altro token che non otterrà loro nulla. Ecco perché hai bisogno di token forti come 'UUID', quindi non possono ottenerli solo per altri utenti. – Zhedar

+5

Il token può essere molto più forte della password dell'utente a causa della sua complessità e del fatto che il token scade per esempio 5 minuti dopo il clic del pulsante. Quando dico token non ho detto random tra 0 e 10, intendo quel tipo di token: nWc^5: lh6 [xM (@ 2t795j? BDZ40vEjT. Questo token è valido forse 5 minuti, quindi l'unico modo per un hacker di crack questo è per hackerare la tua casella di posta/rete ..., non l'applicazione – clement

2

Non è possibile limitare l'indirizzo di posta elettronica al cambiamento da parte dell'utente.
L'indirizzo di posta elettronica può essere facilmente modificato modificando il codice sorgente nel browser anche se è stato nascosto o creato una casella di testo come readonly.

Si può fornire uniq random string or token con il link di reset e controllo l'indirizzo di posta elettronica e la combinazione di token dopo aver cliccato sul link password reset o dopo che l'utente presentato richiesta di reimpostazione della password controllando l'indirizzo e-mail e la stringa di token nella richiesta con l'indirizzo email e Token stringa nel tuo database.

Se l'indirizzo di posta elettronica è presente nel database significa che l'indirizzo di posta elettronica è valido, se non quello di fornire un messaggio che l'indirizzo di posta elettronica non esiste nei record dell'utente.

NOTA:
Se usate un quadro o semplicemente servlet di meglio per fornire collegamento, in modo che è possibile convalidare e-mail e la stringa di token prima di visualizzare il modulo reimpostazione della password. Se la stringa token o l'indirizzo e-mail non sono validi, è possibile limitare l'invio da parte dell'utente della richiesta di reimpostazione della password e convalidare dopo aver inviato la richiesta. Sarà più sicuro della convalida dopo aver inviato la richiesta di reimpostazione della password.

3

Sono d'accordo con la risposta data da @clement se si deve implementare la funzionalità della password dimenticata da soli. Sembra un modo ragionevole e sicuro per questa implementazione.

Tuttavia, in alternativa, se non si deve implementare da soli, suggerirei di utilizzare un servizio che faccia questo per voi, come Stormpath.

Se si decide di utilizzare Stormpath, il codice che farebbe scattare la funzionalità sarebbe simile a questa in Java (con Java SDK di Stormpath):

Account account = application.sendPasswordResetEmail("[email protected]"); 

tuo manuale otterrebbe una e-mail con un link del tipo:

http://yoursite.com/path/to/reset/page?sptoken=$TOKEN 

e poi, quando l'utente fa clic sul link, si dovrebbe verificare e reimpostare la password in questo modo:

Account account = application.resetPassword("$TOKEN", "newPassword"); 

I dettagli su come funziona possono essere trovati in Stormpath password reset documentation.

Con questo approccio non è necessario implementare e mantenere la funzionalità per se stessi se si ha la possibilità di non farlo.

Nota: Stormpath è stato aggiunto a Okta.

+0

grazie mille. Non vedo l'ora di usarlo in futuro – vigamage

+0

Certo, nessun problema. Felice di aiutare! – ecrisostomo

1

ci sono due soluzioni comuni:

1. Creating a new password on the server and inform user from it. 
2. Sending a unique URL to reset password. 

La prima soluzione ha un sacco di problemi e non è opportuno utilizzare. Questi sono alcuni motivi:

1. The new password which is created by server should be sent through an insecure channel (such as email, sms, ...) and resides in your inbox. 

2. If somebody know the email address or phone number of a user who has an account at a website then then it is possible to reset user password. 

Quindi, seconda soluzione è meglio usare. Tuttavia, si dovrebbe prendere in considerazione seguenti problemi:

- The reset url should be random, not something guessable and unique to this specific instance of the reset process. 

- It should not consist of any external information to the user For example, a reset URL should not simply be a path such as “.../?username=Michael”. 

- We need to ensure that the URL is loaded over HTTPS. No, posting to HTTPS is not enough, that URL with the token must implement transport layer 
    security so that the new password form cannot be MITM’d and the password the user creates is sent back over a secure connection. 

- The other thing we want to do with a reset URL is setting token's expiration time so that the reset process must be completed within a certain duration. 

- The reset process must run once completely. So, Reset URL can not be appilicable if the reset process is done completely once. 

La soluzione comune può essere la generazione di un URL per creare un token univoco che può essere inviato come parametro URL, contiene un URL come “Reset/id = 2ae755640s15cd3si8c8i6s2cib9e14a1ae552b? ”.

1

Questa domanda è stata postata 3 anni prima di questa risposta ... Tuttavia penso che potrebbe essere utile per gli altri.

Quindi in breve: sono totalmente d'accordo con il tuo flusso. Sembra molto sicuro, e il tuo unico fine aperto ha anche senso - come puoi assicurarti che nessuno cambi il nome utente, e da questo può impostare una nuova password per lui.

Mi piace meno l'idea di archiviare temporaneamente le cose è il DB (come suggerisce la risposta accettata).

L'idea a cui stavo pensando era di firmare i dati nel collegamento che viene inviato all'utente. Quindi, quando l'utente fa clic sul collegamento e il server riceve la chiamata, il server riceve anche la parte crittografata e può verificare che i dati non siano stati toccati.

A proposito (qui arriva una "promozione"): Ho implementato un progetto JAVA per questi casi d'uso (anche "creare account", "cambiare password" ecc.). È gratuito su GitHub, open source. Risponde perfettamente alla tua domanda ... implementata in Java, in cima a Spring Security.

Non ci sono spiegazioni per ogni cosa (e se manca qualcosa - fatemi sapere ...)

dare un'occhiata: https://github.com/OhadR/oAuth2-sample/tree/master/authentication-flows

Consulta l'Demo here.

C'è anche un client web-app che utilizza le Auth-flussi, con il README con tutte le spiegazioni: https://github.com/OhadR/Authentication-Flows

+0

grazie mille. il modo in cui stai suggerendo sembra molto impressionante – vigamage

Problemi correlati