2017-12-24 10 views
0

Wir haben Asp.Net Core angepasst, um unsere Tabelle der Schüler anstelle der AspNetUser Tabelle zu verwenden. Alles funktioniert gut für neue Studenten. Aber wir müssen die vorhandenen Schülerpasswörter aktualisieren. Ich möchte so etwas wie dies tun (in AccountControllerLogin-Methode), wenn ein Schüler-Anmeldungen oder diese auf eine einmalige Basis getan werden könnte ...Asp.Net Core Identity, Aktualisierung bestehender Klartext Passwörter

[HttpPost] 
[AllowAnonymous] 
[ValidateAntiForgeryToken] 
public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) 
{ 
    ViewData["ReturnUrl"] = returnUrl; 
    if (ModelState.IsValid) 
    { 
     // Require the user to have a confirmed email before they can log on. 
     var user = await _userManager.FindByEmailAsync(model.Email); 
     if (user != null) 
     { 
      if (user.PasswordHash == null) 
      { 
       user.EmailConfirmed = true; 
       user.UserName = model.Email; 
       user.NormalizedEmail = model.Email.ToUpper(); 
       user.NormalizedUserName = user.NormalizedEmail; 
       //user.PasswordHash = ?; 
       //user.SecurityStamp = ?; 
       //update user in database. 
      } 
      //continue on with login process 
     } 
    } 
} 

Der Code unten (von der Register Methode) erstellt einen neuen Benutzer und fügt ihn zur Datenbank hinzu. Das ist nicht was wir wollen.

var user = new ApplicationUser { UserName = model.Email, Email = model.Email }; 
var result = await _userManager.CreateAsync(user, model.Password); 
if (result.Succeeded) 
    // … 
+0

Wie soll sich der Benutzer einloggen, wenn der Passwort-Hash scheinbar "null" ist? Welches Passwort würde der Benutzer dann verwenden, und wie würden Sie überprüfen, dass es der tatsächliche Benutzer ist? – poke

+1

Warum sperren Sie nicht alle Benutzer, die ihr Kennwort ändern sollten, und erklären Sie dann, dass sie ein neues Kennwort mithilfe des Links "Kennwort vergessen" anfordern müssen? Auf diese Weise generiert Identity ein Token zum Zurücksetzen des Kennworts, mit dem die Benutzer dann ihr eigenes Kennwort richtig festlegen können. – poke

+0

Die Schüler melden sich mit ihrem Klartext-Passwort an. Wenn ich eine E-Mail-Adresse und ein Passwort gefunden habe, weiß ich, dass es sich um einen autorisierten Benutzer handelt, zumindest auf dem Niveau der Vergangenheit. - Dieser Code ist bevor Sie an den Punkt gelangen, an dem das Identity-System den Passwort-Hash überprüft. Wenn ich das schaffen könnte, wäre die Änderung für den Benutzer völlig transparent. –

Antwort

0

Sie finden die UserManager hat alles, was Sie das Kennwort für einen Benutzer festlegen müssen. Während Sie das interne Passwort hasher direkt verwenden können, stellt der Benutzermanager sicher, dass die Benutzereinheit in Bezug auf das Passwort korrekt aktualisiert wird. Sie können sich also darauf verlassen, dass der Benutzermanager "das Richtige tut".

Wenn ein Benutzer kein Passwort haben, können Sie AddPasswordAsync es einrichten verwenden:

var user = await _userManager.FindByEmailAsync(model.Email); 
if (user != null && !(await _userManager.HasPasswordAsync(user))) 
{ 
    // retrieve plaintext password 
    var originalPassword = GetPlainTextPassword(user); 

    var result = await _userManager.AddPasswordAsync(user, originalPassword); 

    if (!result.Succeeded) 
    { 
     // handle error 
    } 
} 

Andernfalls könnten Sie auch den Passwort-Reset-Flow machen und einen Token generieren Sie sofort verwenden Sie dann zurücksetzen das Passwort des Benutzers (ohne den Benutzer tatsächlich zu involvieren). Sie würden also grundsätzlich GeneratePasswordResetTokenAsync und ResetPasswordAsync verketten. Natürlich sollte dies nur aus Wartungsgründen erfolgen:

var user = await _userManager.FindByEmailAsync(model.Email); 
if (user != null) 
{ 
    // retrieve plaintext password 
    var originalPassword = GetPlainTextPassword(user); 

    // retrieve token 
    var resetToken = await _userManager.GeneratePasswordResetTokenAsync(user); 

    // reset password 
    var result = await _userManager.ResetPasswordAsync(user, resetToken, originalPassword); 

    if (!result.Succeeded) 
    { 
     // handle error 
    } 
} 

Unabhängig davon, würde ich vorschlagen, Sie noch aktiv Benutzer ihre Passwörter selbst zurücksetzen. Entfernen Sie einfach die Nur-Text-Passwörter aus der Datenbank und behalten Sie das leere Passwort bei. Auf diese Weise müssen Benutzer ihr Passwort zuerst zurücksetzen (Sie sollten eine Notiz hinzufügen, um zu erklären, dass sie dies vor ihrer ersten Anmeldung tun müssen) und Niemand wird jemals in der Lage sein, ihr neues Passwort im Klartext zu sehen. - Die alten Passwörter sind in der Datenbank verfügbar und wahrscheinlich (hoffentlich?) Eine große Anzahl von Backups, und selbst wenn Sie glauben, dass Ihr System sicher ist, ist es wahrscheinlich nicht perfekt. Und es gibt immer noch Leute, die Zugriff auf die Datenbank haben und diese Passwörter direkt oder indirekt anderen zur Verfügung stellen können (mit oder ohne gute Absichten). Sie sollten Ihrem System nicht genug vertrauen, damit nichts schief geht. Und Benutzer sollten nicht darauf vertrauen, dass ihre Passwörter sicher sind. Sie sollten ihnen sagen, ein neues Passwort zu erstellen und ihre alten loszuwerden - besser früher als später.

+1

Danke. Ich denke, das wird funktionieren. Außerdem haben Sie mich davon überzeugt, dass Benutzer ihr Passwort explizit zurücksetzen. Außerdem können wir die Anforderungen für ein stärkeres Passwort erhöhen. –

Verwandte Themen