Reputation: 646
I’m experiencing strange behavior of my ASP.NET MVC 4.0 application. It seems that POST request form data are missing randomly during user login. The application uses form authentication with local user database. I have a simple login screen with form defined as follows:
@using (Html.BeginForm("LogOn" ,"Account", FormMethod.Post))
{
<div>
<table class="editor">
<tr>
<td class="editor-label">
@Html.LabelFor(m => m.UserName)
</td>
<td class="editor-field">
@Html.TextBoxFor(m => m.UserName)
@Html.ValidationMessageFor(m => m.UserName)
</td>
</tr>
<tr>
<td class="editor-label">
@Html.LabelFor(m => m.Password)
</td>
<td class="editor-field">
@Html.PasswordFor(m => m.Password)
@Html.ValidationMessageFor(m => m.Password)
</td>
</tr>
<tr>
<td class="editor-label">
@Html.LabelFor(m => m.RememberMe)
</td>
<td class="editor-field">
@Html.CheckBoxFor(m => m.RememberMe)
</td>
</tr>
</table>
</div>
<input type="submit" value="Přihlásit" />
}
Controller action:
[HttpPost]
public ActionResult LogOn(LogOnModel model, string returnUrl)
{
if (model == null)
throw new ArgumentNullException("model");
CoreServices.Logger.Info("Loggin attemp for user '{0}'. Request UserName: {1}", model.UserName, HttpContext.Request["UserName"]);
if (ModelState.IsValid)
{
if (Membership.ValidateUser(model.UserName, model.Password))
{
CoreServices.Logger.Info("User '{0}' enter valid password.", model.UserName);
FormsAuthentication.SetAuthCookie(model.UserName, model.RememberMe);
if (!string.IsNullOrEmpty(returnUrl) && Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/", StringComparison.Ordinal)
&& !returnUrl.StartsWith("//", StringComparison.Ordinal) && !returnUrl.StartsWith("/\\", StringComparison.Ordinal))
{
CoreServices.Logger.Info("User '{0}' logged in. Redirecting to URL: {1}", model.UserName, returnUrl);
return Redirect(returnUrl);
}
else
{
CoreServices.Logger.Info("User '{0}' logged in. Redirecting to home.", model.UserName);
return RedirectHome();
}
}
else
{
CoreServices.Logger.Info("User '{0}' entered incorrect password. Membership.ValidateUser() returns false.", model.UserName);
ModelState.AddModelError("", "Zadané jméno nebo heslo jsou nesprávné.");
}
}
else
{
CoreServices.Logger.Info("User '{0}' entered invalid password.", model.UserName);
}
// If we got this far, something failed, redisplay form
return View(model);
}
If a user posts login form, posted form values -UserName and Password - are present in the request. I validated that using Fiddler. But on the server, if I check HttpContext.Request["UserName"] in the Account controller, the value is null, despite that UserName value was present in the request.
This behavior occurs randomly and it is not dependent on browser (reported on IE9, FF 25, Chrome 24). The application is hosted on IIS7, integrated pipeline mode, SSL is used with self-signed certificate (but it occurs even if SSL is not used). It is almost impossible to reproduce it in development environment (it saw this behavior twice on our server in DEV), but it is common in production environment (in which I do not have access, unfortunately).
Do you have any idea how to solve this issue? Can I monitor somehow, what is cause of missing values?
Thank you
Upvotes: 0
Views: 1722
Reputation: 646
The reason probably is that IE sends "0" in "content length" parameter in HTTP header on POST, despite the fact that the body of the request has non-zero content (contains form data). Request with existing form data but "0" content length is not processed correctly on IIS and values are not available in HttpContext.Request. According article Challenge-Response Authentication and Zero-Length Posts this is happenning if browser issue a reqeust to a secure part of a website which ask user for authorization using credentials. After that requst the IE expects that next POST request is bodyless response to that credential request. See linked article for details.
Upvotes: 1