4

Even though I am running in localhost, my mvc web site gives me this error:

The anti-forgery token could not be decrypted. If this application is hosted by a Web Farm or cluster, ensure that all machines are running the same version of ASP.NET Web Pages and that the configuration specifies explicit encryption and validation keys. AutoGenerate cannot be used in a cluster.

I used this machinekey:

<machineKey compatibilityMode="Framework20SP1" validationKey='AC0DA63E787522E3BA5D47D8FA0A46EB68BB89A35C6353D5E8D3D5CA416D0DA607E56C6D0861ED3B7194C3ED74C0CE79FE4CE2909F34A6CFBDE134C1A094CA40' decryptionKey='A68360896EF374401123C6C222A7AAD8D430DB4DE34938E1' validation='SHA1'/>

But still no use. In addition, I extracted this machinekey from a third party. I know it is not safe but the microsoft way is too complicated: using powershell to generate it? complicated. Then using IIS? My IIS8 is not showing machinekey module. What on earth is going on with all of these stuff.

Okay, maybe the error is caused by a multiple @html.antiforgerytoken. Well, I had indeed two antiforgerytoken, but when I remove one of them, the error persisted.

I am so frustated with this problem. I hope someone will be kind enough to help. I believe those MVC users have been in this situation when developing MVC web site. In my case, I am just a newbie and this is my first MVC web site that is deployed.

thanks for you help

UPDATE

controller:

// POST: /Account/Manage
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Manage(ManageUserViewModel model)
    {
        bool hasPassword = HasPassword();
        ViewBag.HasLocalPassword = hasPassword;
        ViewBag.ReturnUrl = Url.Action("Manage");
        if (hasPassword)
        {
            if (ModelState.IsValid)
            {
                IdentityResult result = await UserManager.ChangePasswordAsync(User.Identity.GetUserId(), model.OldPassword, model.NewPassword);
                if (result.Succeeded)
                {
                    return RedirectToAction("Manage", new { Message = ManageMessageId.ChangePasswordSuccess });
                }
                else
                {
                    AddErrors(result);
                }
            }
        }
        else
        {
            // User does not have a password so remove any validation errors caused by a missing OldPassword field
            ModelState state = ModelState["OldPassword"];
            if (state != null)
            {
                state.Errors.Clear();
            }

            if (ModelState.IsValid)
            {
                IdentityResult result = await UserManager.AddPasswordAsync(User.Identity.GetUserId(), model.NewPassword);
                if (result.Succeeded)
                {
                    return RedirectToAction("Manage", new { Message = ManageMessageId.SetPasswordSuccess });
                }
                else
                {
                    AddErrors(result);
                }
            }
        }

        // If we got this far, something failed, redisplay form
        return View(model);
    }

View:

@using percobaan2.Models;
@using Microsoft.AspNet.Identity;
@{
ViewBag.Title = "Manage Account";
Layout = "~/Views/Shared/_LayoutManage.cshtml";
}

<div class="row-fluid">
<div class="span4 offset4 blog-details">

    <p class="text-success">@ViewBag.StatusMessage</p>

    @using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
    {
        @Html.AntiForgeryToken()
        @Html.ValidationSummary(true)

        <article class="center">

            @if (ViewBag.HasLocalPassword)
            {
                @Html.Partial("_ChangePasswordPartial")
            }
            else
            {
                @Html.Partial("_SetPasswordPartial")
            }

        </article>
    }
</div>
</div>

@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}

Layout:

<!DOCTYPE html>
<html lang="en">
<head>
<!-- META DATA -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=0, minimum-scale=1.0, maximum-scale=1.0">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">

<meta name="description" content="@ViewBag.WebsiteTitle">

<title>@ViewBag.Title - @ViewBag.WebsiteTitle</title>

<link rel="shortcut icon" href="assets/images/ico/favicon.png">

@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/modernizr")

<!-- GOOGLE WEB FONTS -->
<link href='http://fonts.googleapis.com/css?family=Open+Sans:300italic,400italic,600italic,700italic,800italic,400,700,600,300,800' rel='stylesheet' type='text/css'>
</head>
<body>

<!-- NAVIGATION -->
<nav class="fixed-top fixed-visable" id="navigation">
    <div class="container">
        <div class="row-fluid">
            <div class="span12 center">
                <!-- MOBILE MENU BUTTON -->
                <div class="mobile-menu" data-toggle="collapse" data-target=".nav-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </div>
                <!-- END MOBILE MENU BUTTON -->
                <!-- MAIN MENU -->
                <ul id="main-menu" class="nav-collapse collapse">
                    <li><a href="@Url.Action("Edit", "Home", new { Area = "Admin", id = 1 })">Home</a></li>
                    <li><a href="@Url.Action("Index", "Slide", new { Area = "Admin" })">Tagline</a></li>
                    <li><a href="@Url.Action("Index", "Division", new { Area = "Admin" })">Division</a></li>
                    <li><a href="@Url.Action("Index", "Contact", new { Area = "Admin" })">Yahoo</a></li>
                    <li><a href="@Url.Action("Index", "Email", new { Area = "Admin" })">Email</a></li>
                    <li><a href="@Url.Action("Index", "Product", new { Area = "Admin" })">Product</a></li>
                    <li><a href="@Url.Action("Index", "Category", new { Area = "Admin" })">Category</a></li>
                    <li><a href="@Url.Action("Index", "Producer", new { Area = "Admin" })">Producer</a></li>
                    <li><a href="@Url.Action("Index", "Unit", new { Area = "Admin" })">Unit</a></li>
                    <li><a href="@Url.Action("Index", "Activity", new { Area = "Admin" })">Activity</a></li>
                    @*@Html.Partial("_LoginPartial")*@
                </ul>
                <!-- END MAIN MENU -->
            </div>
        </div>
    </div>
</nav>
<!-- END NAVIGATION -->
<!-- PAGE | BLOG -->
<div class="pages page-blog-list" id="page-blog-list">
    <div class="container">
        <!-- Header -->
        <header id="headerUpper" class="headerAdmin">
            <h4 class="line-divider">Admin</h4>
            <h1>Change Password</h1>
        </header>
        <!-- End Header -->

            @RenderBody()

    </div>
</div>
<!-- END PAGE | BLOG -->

@Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/bootstrap")
@Scripts.Render("~/bundles/plugins")
@Scripts.Render("~/bundles/blog")
@RenderSection("scripts", required: false)
</body>
</html>

Login Partial:

@using Microsoft.AspNet.Identity
@if (Request.IsAuthenticated)
{
using (Html.BeginForm("LogOff", "Account", new { Area = "" }, FormMethod.Post, new { id = "logoutForm" }))
{
    @Html.AntiForgeryToken()

    <li>
        @Html.ActionLink("Account", "Manage", "Account", new { Area = "" }, htmlAttributes: new { title = "Manage" })
    </li>

    <li>
        <a href="javascript:document.getElementById('logoutForm').submit()">
            Log off
        </a>
    </li>

    @*<li>
            @Html.ActionLink("Account", "Manage", "Account", new { Area = "" }, htmlAttributes: new { title = "Manage", @class = "phoneNumber" })
        </li>

        <li>
            <a href="javascript:document.getElementById('logoutForm').submit()" class="phoneNumber logOffPadding">
                Log off
            </a>
        </li>*@

}
}
else
{
@*@Html.ActionLink("Register", "Register", "Account", new { Area = "" }, htmlAttributes: new { id = "registerLink", @class = "phoneNumber" })*@

<li>
    @Html.ActionLink("Log in", "Login", "Account", new { Area = "" }, htmlAttributes: new { id = "loginLink", @class = "phoneNumber logInPadding" })
</li>
}

.NET Vesion: 4.5

Ace Supriatna
  • 235
  • 1
  • 4
  • 19

3 Answers3

5

In my case it was caused by the anti-forgery token being applied twice in the same form. ref https://stackoverflow.com/a/28620686/662403

Community
  • 1
  • 1
maurox
  • 1,254
  • 1
  • 19
  • 33
  • I had the same problem: Two calls to `@Html.AntiForgeryToken` within the same form caused all submits to fail. Thanks for the hint. – Danielku15 Jun 19 '17 at 11:49
3

Are you using IIS or IIS Express? If you are using ISS Express you are probably generating a new 'site' every time you hit debug from Visual Studio. If so does deleting the cookies in the browser (for localhost) fix the problem? (the cookies are where the authentication information is stored)

If you are using ISS Express you might want to switch to IIS for development (You will have to learn it sooner or later)

If you are using IIS you may need to register a module. I think you are missing the following lines line from your web.config:

<securityTokenHandlers>
   <add type="System.IdentityModel.Services.Tokens.MachineKeySessionSecurityTokenHandler, System.IdentityModel.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
   <remove type="System.IdentityModel.Tokens.SessionSecurityTokenHandler, System.IdentityModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
</securityTokenHandlers>

Have a look at the following links:

Configuring Machine Key protection of session tokens

Using WIF Session tokens

That being said this is confusing stuff, the funny thing is that this stuff works out of the box when you create a new MVC project, you might want to track down what you changed to stop it working. Do you need to have a machine key? Are you going to be running this on a server farm or in a load balanced environment.

We have had the same issue when using Azure and swapping from staging to production as both machines were different. We ended up signing our authentication tokens with a ssl certificate so we avoided sharing a machine key.

P.S. Posting your web.config would probably help in diagnosing this problem.

Aran Mulholland
  • 23,555
  • 29
  • 141
  • 228
2

Ensure you have SSL enabled on your project.

Even if you using a third party generated machine key.

themikola
  • 124
  • 3