2017-12-24 58 views
0

AspNetUser 테이블 대신 학생 테이블을 사용하도록 Asp.Net Core를 사용자 정의했습니다. 새로운 학생들에게는 모든 것이 잘 작동합니다. 그러나 기존 학생의 비밀번호를 업데이트해야합니다. 이 일회성으로 학생 로그인 또는 할 수있을 때 나는Asp.Net 핵심 ID, 기존 일반 텍스트 암호를 업데이트

[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 
     } 
    } 
} 

합니다 (Register 방법에서) 아래의 코드는 새 사용자를 생성 ... (AccountControllerLogin 방법) 같은 것을 할 싶습니다 그를 데이터베이스에 추가합니다. 이것은 우리가 원하는 것이 아닙니다.

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

암호 해시가 'null'일 때 사용자가 어떻게 로그인해야합니까? 사용자가 사용하는 비밀번호는 무엇이며, 실제 사용자인지 어떻게 확인합니까? – poke

+1

비밀번호를 변경해야하는 모든 사용자를 잠그고 "잊어 버린 비밀번호"링크를 사용하여 새 비밀번호를 요청해야한다고 설명하는 이유는 무엇입니까? 그렇게하면 Identity는 사용자가 자신의 암호를 올바르게 설정하는 데 사용할 수있는 암호 재설정 토큰을 생성합니다. – poke

+0

학생들은 평문 암호로 로그인하게됩니다. 전자 메일과 암호가 일치하면 적어도 과거에 있었던 수준의 권한이 부여 된 사용자라는 것을 알고 있습니다. -이 코드는 Identity 시스템이 암호 해시를 확인하는 시점에 도달하기 전에 나타납니다. 이 작업을 수행 할 수 있다면 변경 사항은 사용자에게 완전히 투명하게 전달됩니다. –

답변

0

당신은 UserManager 찾을 수 있습니다 당신이 사용자의 암호를 설정해야합니다 아무것도있다. 내부 암호 해시를 직접 사용할 수는 있지만 사용자 관리자를 거치면 사용자 엔티티가 암호와 관련하여 올바르게 업데이트되었는지 확인할 수 있습니다. 따라서 사용자 관리자에게 "올바른 작업 수행"을 의지 할 수 있습니다.

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 
    } 
} 

그렇지 않으면, 당신은 또한 암호 재설정 흐름의 사용을 만들 수있는 당신이 즉시 재설정하는 데 사용하는 토큰을 생성 : 사용자가 암호가없는 경우

, 당신은 그것을 설정하는 AddPasswordAsync을 사용할 수 있습니다 사용자의 암호 (실제로 사용자를 포함하지 않음). 따라서 기본적으로 GeneratePasswordResetTokenAsyncResetPasswordAsync을 연결합니다. 물론, 이것은 단지 유지 보수를 이유로 수행해야합니다 :

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 
    } 
} 

에 관계없이이의, 나는 아직도 당신이 적극적으로 가 암호 자체를 재설정 사용자가 필요로하는 것이 좋습니다 것입니다. 그냥 일반 텍스트 암호를 데이터베이스에서 제거하고 빈 암호를 유지하십시오. 그렇게하면 사용자는 먼저 비밀번호를 재설정해야합니다 (처음 로그인하기 전에 메모를 추가해야 함). nobody은 평문으로 새 비밀번호를 볼 수 있습니다. - 이전 암호가 데이터베이스에 노출되어 있고 많은 수의 백업이있을 가능성이 있으며, 시스템이 안전하다고해도 완벽하지는 않습니다. 그리고 데이터베이스에 액세스 할 수있는 사람들이 여전히 있으며 직접 또는 간접적으로 다른 사람들에게 (좋은 의도의 유무에 관계없이) 암호를 노출 할 수 있습니다. 아무 것도 잘못되지 않도록 시스템을 충분히 신뢰해서는 안됩니다. 사용자는 자신의 암호를 안전하게 유지해야하는 것을 신뢰해서는 안됩니다. 새로운 암호를 만들고 이전 암호를 제거하도록 나중에 알려야합니다.

+1

감사합니다. 나는 이것이 효과가있을 것이라고 생각한다. 또한 사용자가 명시 적으로 비밀번호를 재설정하도록 나를 설득했습니다. 또한 우리는보다 강력한 암호를 요구할 수 있습니다. –