2015-02-23 16 views
8

Khi tôi gọi mã dưới đây, tôi luôn nhận được result.Succeeded = falseTại sao ResetPasswordAsync không hoạt động?

 [HttpPost] 
     [AllowAnonymous] 
     [ValidateAntiForgeryToken] 
     public async Task<ActionResult> ResetPassword(ResetPasswordViewModel model) 
     { 
      if (!ModelState.IsValid) 
      { 
       return View(model); 
      } 
      var user = await UserManager.FindByNameAsync(model.Email); 
      if (user == null) 
      { 
       // Don't reveal that the user does not exist 
       return RedirectToAction("ResetPasswordConfirmation", "Account"); 
      } 
      string code = await UserManager.GeneratePasswordResetTokenAsync(user.Id); 
      var result = await UserManager.ResetPasswordAsync(user.Id, code, model.Password); 
      //var result = await UserManager.ResetPasswordAsync(user.Id, model.Code, model.Password); 
      if (result.Succeeded) 
      { 
       return RedirectToAction("ResetPasswordConfirmation", "Account"); 
      } 
      AddErrors(result); 
      return View(); 
     } 

Các giá trị cho user.Id và mật khẩu là hợp lệ. Các lỗi kết quả luôn luôn nói "Mã thông báo không hợp lệ" mà tôi không thấy càng tốt kể từ khi tôi nhận được nó và ngay lập tức kiểm tra nó và nó lỗi. Đây chỉ là một thử nghiệm sanity - tôi thường gửi mã thông báo qua email cho người dùng nhưng điều đó không hoạt động.

UPDATE 1 tôi xác định UserManager trong bộ điều khiển tương tự như thế này:

private ApplicationSignInManager _signInManager; 
    private ApplicationUserManager _userManager; 

    public AccessController() 
    { 
    } 

    public AccessController(ApplicationUserManager userManager, ApplicationSignInManager signInManager) 
    { 
     UserManager = userManager; 
     SignInManager = signInManager; 
    } 

    public ApplicationSignInManager SignInManager 
    { 
     get 
     { 
      return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>(); 
     } 
     private set 
     { 
      _signInManager = value; 
     } 
    } 

    public ApplicationUserManager UserManager 
    { 
     get 
     { 
      return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
     } 
     private set 
     { 
      _userManager = value; 
     } 
    } 

UPDATE 2 Đây là mã ApplicationUserManager tôi:

public class ApplicationUserManager : UserManager<ApplicationUser> 
{ 
    public ApplicationUserManager(IUserStore<ApplicationUser> store) 
     : base(store) 
    { 
    } 

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    { 
     var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>())); 
     // Configure validation logic for usernames 
     manager.UserValidator = new UserValidator<ApplicationUser>(manager) 
     { 
      AllowOnlyAlphanumericUserNames = false, 
      RequireUniqueEmail = true 
     }; 

     // Configure validation logic for passwords 
     manager.PasswordValidator = new PasswordValidator 
     { 
      RequiredLength = 6, 
      RequireNonLetterOrDigit = true, 
      RequireDigit = true, 
      RequireLowercase = true, 
      RequireUppercase = true, 
     }; 

     // Configure user lockout defaults 
     manager.UserLockoutEnabledByDefault = true; 
     manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); 
     manager.MaxFailedAccessAttemptsBeforeLockout = 5; 

     // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user 
     // You can write your own provider and plug it in here. 
     manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser> 
     { 
      MessageFormat = "Your security code is {0}" 
     }); 
     manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser> 
     { 
      Subject = "Security Code", 
      BodyFormat = "Your security code is {0}" 
     }); 
     manager.EmailService = new EmailService(); 
     manager.SmsService = new SmsService(); 
     var dataProtectionProvider = options.DataProtectionProvider; 
     if (dataProtectionProvider != null) 
     { 
      manager.UserTokenProvider = 
       new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity")); 
     } 
     return manager; 
    } 
} 
+1

Làm thế nào để bạn tạo ra trường hợp của 'UserManager'? Rất có thể trường hợp đó của 'IDataProtectionProvider' được tạo lại và nó sẽ giữ nguyên để xác thực mã. – trailmax

+0

Bạn có mã thông báo AntiForgery của mình trong biểu mẫu không? Đăng mã mẫu của bạn – Luca

+0

@Luca Nếu mã thông báo chống giả mạo không hợp lệ, ngoại lệ sẽ sớm hơn vấn đề hiện tại và quá trình xử lý sẽ không đến giai đoạn tạo mã thông báo. – trailmax

Trả lời

19

Đây là một shot dài, nhưng nếu UserManager của bạn tuyên bố rằng nó hỗ trợ tem bảo mật người dùng thì hãy đảm bảo rằng ở cấp cơ sở dữ liệu người dùng có một tem bảo mật hợp lệ, cụ thể hơn, nó phải không có tem NULL.

Lý do là khi tạo mã, nếu dấu đến là null thì nó được thay thế bằng string.Empty và được sử dụng trong mã đặt lại được tạo. Tuy nhiên, khi xác nhận mã đặt lại, con tem đến từ nó sẽ được so sánh trực tiếp với những gì xuất phát từ cơ sở dữ liệu, do đó bạn có thể kết thúc so sánh string.Empty với null và không xác thực được.

Từ ASP NET nhận dạng đang 2.2 nguồn cho DataProtectorTokenProvider (nó là như nhau trong phiên bản trước):

// GenerateAsync method 
if (manager.SupportsUserSecurityStamp) 
{ 
    stamp = await manager.GetSecurityStampAsync(user.Id); 
} 
writer.Write(stamp ?? ""); // Written as "" if null 


// ValidateAsync method 
if (manager.SupportsUserSecurityStamp) 
{ 
    var expectedStamp = await manager.GetSecurityStampAsync(user.Id).WithCurrentCulture(); 
    return stamp == expectedStamp; // Read as "" but compared directly to null 
} 
+0

Bùng nổ! Điều đó là vậy đó! SecurityStamp là NULL. Tôi đặt một guid trong đó và nó hoạt động tốt. Tôi không hoàn toàn chắc chắn lý do tại sao nó là NULL nhưng bây giờ tôi hiểu nơi mà vấn đề được, tôi có thể sử dụng mã của bạn ở trên và tìm ra lý do tại sao nó là null và làm thế nào để sửa chữa nó đi về phía trước. – EdenMachine

+0

Chỗ tốt! Hoàn toàn bỏ lỡ tùy chọn này! – trailmax

+0

Mã thông báo đặt lại của tôi hoạt động lạ lùng trên hệ thống dev của tôi nhưng không hoạt động trên máy chủ sản xuất. Điều này cố định nó. – damccull

Các vấn đề liên quan