2013-03-02 57 views
1

我在MVC4应用程序中使用SimpleMembership,并且需要用户更改自己的用户名的功能。SimpleMembership正在更改用户名

我有功能工作,所以当用户更改他们的用户名它的作品。但是,当调用诸如Roles.IsUserInrole()之类的东西时,它会失败,因为User.Identity.Name被设置为他们登录的内容,而不是新值。该值不再存在于数据库中,因为它们已更改名称。

我看不到用户名更新登录用户上下文的方法。大多数情况下,我可以在会话中存储用户ID并在进行查询时检索它,但是我使用Roles方法在视图中显示失败的数据。

任何想法?

谢谢!

回答

0

我不认为你能够改变用户名字段(如果你能告诉我你是如何实现这一目标的话,会很好)。

我看到的唯一解决方案是强制用户在更改用户名后注销,因此当他们重新登录时他们将拥有正确的User.Identity.Name。

+0

你也可以要求用户输入时,用户更改用户名的密码,它增强了安全性,加上这意味着你可以注销用户并马上将它们重新登录(例如,参见David的答案),因此会话帐户信息将是正确的。 – raf 2014-09-10 02:43:13

5

这是我目前(工作)解决方案:

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Edit(AccountEditModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      if (HasSensitiveInformationChanged(model)) // model.EmailAddress.ToLower() != User.Identity.Name.ToLower() 
      { 
       if (Membership.ValidateUser(User.Identity.Name, model.Password)) // && WebSecurity.IsCurrentUser(User.Identity.Name)) //redundant? 
       { 
        using (UsersContext db = new UsersContext()) 
        { 
         UserProfile user = db.UserProfiles.FirstOrDefault(u => u.EmailAddress.ToLower() == User.Identity.Name.ToLower()); 

         if (user != null) 
         { 
          user.EmailAddress = model.EmailAddress; 
          db.SaveChanges(); 
          WebSecurity.Logout(); 
          WebSecurity.Login(model.EmailAddress, model.Password); 
          return RedirectToAction("Index", "Search"); 
         } 
         else 
         { 
          ModelState.AddModelError("", "Could not find user. Please try logging in again."); 
         } 
        } 
       } 
       else 
       { 
        ModelState.AddModelError("","Could not change email address. Please verify your password and try again."); 
       } 
      } 
      else 
      { 
       //no change 
       return RedirectToAction("Index", "Search"); 
      } 
     } 

     return View("Index", model); 
    }