我在表单提交后遇到了防伪标记问题。我一直收到这个错误消息:
“提供的防伪标记是为用户“{user}”准备的,但当前用户为空”
与其他人提出的问题不同的是,我的问题是它说当前用户为空,而防伪标记正在寻找一个用户。这毫无意义,因为当我检查HttpContext.Current.User.Identity.Name和Membership.GetUser().UserName时,它们确实拥有防伪标记正在寻找的用户。这真的没有任何意义。
NewRecordEntry.cshtml
“提供的防伪标记是为用户“{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
验证登录
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;
}
HttpContext.Current.User = principal;
如果你把它移除,程序会正常运行。但是,我不确定为什么或者有什么好的解决方案。我目前将 Thread.Current 设置为 principal,但这并不总是有效。 - Mrchief