提供的防伪令牌适用于用户“{user}”,但当前用户为“”

时间:2014-12-03 15:15:30

标签: asp.net asp.net-mvc

表单提交后,我的防伪令牌出现问题。我继续收到此错误消息:

  

提供的防伪令牌适用于用户“{user}”,但当前用户为“”

其他人在这里和我的问题之间的区别在于它说当前用户是空白的并且防伪令牌正在寻找用户。这没有任何意义,因为当我检查 HttpContext.Current.User.Identity.Name Membership.GetUser()。UserName 时,他们确实有用户防伪标记是寻找。这没有任何意义。

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

2 个答案:

答案 0 :(得分:0)

您应该检查表单中是否有多个@Html.AntiForgeryToken()。如果是,请删除除一个以外的所有内容。

同时确保您没有提交表格两次。这会弄乱AntiForgeryToken

如果要停用此检查,请将以下内容添加到Application_Start方法中:

AntiForgeryConfig.SuppressIdentityHeuristicChecks = true

答案 1 :(得分:0)

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

解决方案可能是将FakeAuthenticationFilter放在NewRecordEntry Action上。