Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC 3 web site anti-forgery token fails only on IE

In my MVC 3 project i have a login page that uses the anti-forgery logic built into MVC 3.

On Firefox & Opera it works just fine, but on IE I get this:

A required anti-forgery token was not supplied or was invalid.

I'm really stumped on why only IE suffers this, I checked the cookie settings and they are set the same as the other browsers so I'm at a lost here.

When I use the anti forgery code, I use both a SALT and the domain check (which shouldn't matter but worth telling).

Here is the view code:

@model login.Models.LogOnModel

@{
    ViewBag.Title = "Log On";
}

<script src="@Url.Content("~/Scripts/jquery.validate.min.js")" type="text/javascript"> </script>
<script src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")" type="text/javascript"></script>

<script type="text/javascript">
$(function () {
    //focus on form.
    $("#UserName").focus();
});
</script>

 @using (Html.BeginForm("LogOn", "Account", FormMethod.Post, new { @class = "form login" })) {
@Html.AntiForgeryToken("!@#Hq4(", ViewBag.AppDomain, "/")
<div id="box">
<h1>Login</h1>
Please enter your username and password. @Html.ActionLink("Register", "Register") if you don't have an account.
<div class="block" id="block-login">
    <h2>
        Login Form</h2>
    <div class="content login">
              @Html.ValidationSummary(true)
        <div class="group buffer">
            <div class="left">
                <label class="label right">
                    @Html.LabelFor(m => m.UserName)</label>
            </div>
            <div class="right">
                @Html.TextBoxFor(m => m.UserName, new { @class = "text_field" })
                @Html.ValidationMessageFor(m => m.UserName)
            </div>
        </div>
        <div class="group buffer">
            <div class="left">
                <label class="label right">
                    @Html.LabelFor(m => m.Password)</label>
            </div>
            <div class="right">
                @Html.PasswordFor(m => m.Password, new { @class = "text_field" })
                @Html.ValidationMessageFor(m => m.Password)
            </div>
        </div>
        <div class="group buffer">
            <div class="left">
                <label class="label right">
                    @Html.LabelFor(m => m.RememberMe)</label>
            </div>
            <div class="right">
                @Html.CheckBoxFor(m => m.RememberMe)
            </div>
        </div>
        <div class="group navform buffer">
            <div class="right">
                <button class="button" type="submit">
                    <img src="@Url.Content("~/Content/images/icons/key.png")" alt="Save" />
                    Login
                </button>
            </div>
        </div>
    </div>
</div>
</div>
}

ViewBag.AppDomain is a value from web.config for easy setting during testing and production usage.

If I remove the domain and path portion from the antiforgery tag, it works just fine. So one of those two must be the problem.

like image 355
Eman Avatar asked Dec 22 '11 13:12

Eman


2 Answers

I had a similar problem like this when using a custom AntiCSRF token creator. I wasn't using MVC3 but it might be a similer issue.

The issue for me was that the domain name I was using locally for testing the site had an underscore in it. In theory a DNS name cannot have an underscore (even though a "computer name" can), so IE wasn't saving the cookies.

It may not be the same issue, but could be something related to a testing environment and the way cookies are hanlded by IE.

Here is a very interesting article about the internals of IE cookie handling which might help you uncover the issue.

http://blogs.msdn.com/b/ieinternals/archive/2009/08/20/wininet-ie-cookie-internals-faq.aspx

like image 62
Alex KeySmith Avatar answered Sep 30 '22 12:09

Alex KeySmith


I had the same problem as this in an MVC3 project built in VS2010 and viewed through IE 11 (it works fine in Firefox).

The way that I managed to get around it was by adding cookieless="UseCookies" to the "forms" element in the web.config file in the root directory:

<authentication mode="Forms">
  <forms loginUrl="~/Account/LogIn" timeout="2880" slidingExpiration="true" requireSSL="false" cookieless="UseCookies"/>
</authentication>
like image 23
Ally Avatar answered Sep 30 '22 12:09

Ally