2014-12-03 1274 views
2

表单提交后,我的防伪标记存在问题。我不断收到此错误信息:提供的防伪标记用于用户“{user}”,但当前用户为“”

所提供的防伪标记是为那些用户“{用户}”,但当前用户是“”

之间有什么其他的都问的区别在这里和我的是,这是说当前用户是空白的,反伪造令牌正在寻找一个用户。这是没有意义的,因为当我检查HttpContext.Current.User.Identity.NameMembership.GetUser()。用户名,他们确实有用户防伪令牌正在寻找。这没有任何意义。

NewRecordEntry.cshtml

<h2>New Record</h2> 
@using (Html.BeginForm()) 
{ 
    @Html.AntiForgeryToken() 
    <div id="new-record-entry"> 
     @Html.DropDownListFor(model => model.recordTypeID, Model.GetRecordTypeList()) 
    </div> 

    <input type="submit" name="NewRecordEntry" id="continue" size="11" /> 
} 

控制器

[HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult NewRecordEntry(FormCollection frm, NewRecordEntryViewModel nrevm) 
    { 
     TempData["NewRecordEntry"] = nrevm; 
     return RedirectToAction("NewRecord", "FakeController"); 
    }  

身份验证筛选

public class FakeAuthenticationFilter : ActionFilterAttribute, IAuthenticationFilter 
{ 
    public void OnAuthentication(AuthenticationContext filterContext) 
    { 
     // Get userData stored in a session. Workplace environment does not allow cookies 
     UserData userData = (UserData) filterContext.HttpContext.Session[UserInfo.SessionUser]; 
     if (userData != null) 
     { 
      // Get identity and principal 
      var identity = new GenericIdentity(UserInfo.SessionUser, "Forms"); 
      var principal = new FakePrincipal(identity); 

      principal.UserData = userData; 

      // Set the context user. 
      HttpContext.Current.User = principal; 
     } 
     else 
     { 
      filterContext.Result = new RedirectResult("~/Login"); 
     } 
    } 

    public void OnAuthenticationChallenge(AuthenticationChallengeContext filterContext) 
    { 
    } 
    } 

会员

public class FakeMembershipProvider : MembershipProvider 
{ 
    public override bool ValidateUser(string username, string password) 
    { 
     // Check if this is a valid user. 
     // The application sends the username and password to an LDAP DLL which 
     // reurns "Success" if it was a match. 
     string result = LoginService.AuthenticateUser(username, password); 
     if (result == "Success") 
     { 
      return true; 
     } 
     return false; 
    } 

    public override MembershipUser GetUser(string username, bool userIsOnline) 
    { 

     if (LoginService.UserData != null) 
     { 
      return new MembershipUser("FakeMembershipProvider", 
       username, LoginService.UserData.UserID, 
       null, null, null, true, false, 
       DateTime.MinValue, DateTime.MinValue, DateTime.MinValue, 
       DateTime.MinValue, DateTime.MinValue); 
     } 
     return null; 
    } 
} 

登录后控制器

#region Login Post Controllers 
    [HttpPost] 
    [ValidateAntiForgeryToken] 
    public ActionResult Login(FormCollection frm, LoginViewModel lvm, string returnUrl) 
    { 
     List<string> errorList = null; 
     try 
     { 

      if (ModelState.IsValid) 
      { 
       string result = Services.ValidateLogin(lvm); 

       if (result == "Success") 
       { 
        if (Url.IsLocalUrl(returnUrl) 
         && returnUrl.Length > 1 
         && returnUrl.StartsWith("/") 
         && !returnUrl.StartsWith("//") 
         && !returnUrl.StartsWith("/\\")) 
        { 
         return base.Redirect(returnUrl); 
        } 
        return base.RedirectToAction("Index"); 
       } 
       else 
       { 
        TempData["errors"] = result; 
        ModelState.AddModelError("", result); 
       } 
      } 
      else 
      { 
       errorList = Services.AddErrorMesagesToView(ModelState); 
       TempData["errors"] = errorList; 
      } 
      //return base.RedirectToAction("Admin", new { section = section }); 
      ModelState.Clear(); 
      return View(new LoginViewModel()); 
     } 
     catch (NullReferenceException ne) 
     { 
      if (ne.Source != null) 
       Console.WriteLine("NullReferenceException source: {0}", ne.Source); 
     } 
     catch (HttpException he) 
     { 
      if (he.Source != null) 
       Console.WriteLine("HttpException source: {0}", he.Source); 
     } 
     catch (Exception e) 
     { 
      if (e.Source != null) 
       Console.WriteLine("Exception source: {0}", e.Source); 
     } 
     finally 
     { 
      ModelState.Clear(); 
     } 

     return base.RedirectToAction("Login"); 
    } 
    #endregion 

ValidateLogin

public static string ValidateLogin(LoginViewModel lvm) 
    { 
     /* string ldapServer = WebConfigurationManager.AppSettings["LDAPServer"]; 
     string result = Fakeauthenticate.Fakeauth.LdapAuth(lvm.Login, lvm.Password, ldapServer); 
     */ 
     string result = null; 
     const int INACTIVE = 1; 

     FakeEntities db = new FakeEntities(); 

     // This is the only feasible way to call an SQL user-defined scalar function 
     string sqlQuery = "SELECT [dbo].[Util_GetUserActivationStatus] ({0})"; 
     Object[] parameters = { lvm.Login }; 
     int status = db.Database.SqlQuery<int>(sqlQuery, parameters).FirstOrDefault(); 

     if (status == INACTIVE) 
     { 
      return "The user is currently locked out."; 
     } 

     if (Membership.ValidateUser(lvm.Login, lvm.Password)) 
     { 
      HttpContext.Current.Session[UserInfo.SessionUser] = LoginBusiness.GetUserData(lvm.Login); 
      HttpContext.Current.Session.Timeout = UserInfo.Timeout; 

      result = "Success"; 
     } 
     else 
     { 
      result = LoginBusiness.AuthenticateUser(lvm.Login, lvm.Password); 
      if (result == "Login_Failure") 
      { 
       if (HttpContext.Current.Session[lvm.Login] == null) 
       { 
        HttpContext.Current.Session[lvm.Login] = 1; 
       } 
       else 
       { 
        uint loginFailures = (uint)HttpContext.Current.Session[lvm.Login]; 
        HttpContext.Current.Session[lvm.Login] = ++loginFailures; 

        // If the maximum number of login failures have been reached, then lock the user out. 
        if ((uint)HttpContext.Current.Session[lvm.Login] == UserInfo.MAX_LOGIN_FAILURES) 
        { 
         db.Util_LockUserOut(lvm.Login); 
         return "Your account has been temporarily locked."; 
        } 
       } 
      } 
     } 

     return result; 
    } 
+0

显示一些代码也许? – 2014-12-03 15:34:52

+0

什么部分的代码显示? – 2014-12-03 16:04:07

+0

您认为相关的零件... – 2014-12-03 16:07:22

回答

0

你应该检查是否有您的形式不止一个@Html.AntiForgeryToken()。如果是,请除去一个。

此外请确保您没有提交表单两次。这会搞乱AntiForgeryToken

如果要禁用此检查,将以下添加到您的Application_Start方法:

AntiForgeryConfig.SuppressIdentityHeuristicChecks = true 
+0

这基本上是唯一的方法吗? – 2014-12-03 16:04:46

+0

这取决于。你在哪里使用这个反伪造令牌? – 2014-12-03 16:07:45

+0

当我即将创造一个新纪录的时候,第一个网页要求记录的类型。这是一种形式。之后,它会根据类型转到新记录表单。顺便说一下,我尝试了你的建议,但仍然无效。 – 2014-12-03 16:50:15

0

问题就出在你的FakeAuthenticationFilter。我猜你正在加载页面的控制器动作上使用这个过滤器。 FakeAuthenticationFilter设置HttpContext.Current.User =新的FakePrincipal(标识)。此主体可能具有Name属性,这是您在错误消息中看到的用户。 .NET使用此委托人在页面上生成令牌,但是当您提交令牌时,HttpContext将不具有相同的委托人。

一个解决方案可能是将FakeAuthenticationFilter放在您的NewRecordEntry操作上。