ASP.NET MVC Core 2.0 Cookie身份验证因HttpPost ValidateAntiForgeryToken失败

时间:2018-02-07 02:41:33

标签: c# http-post asp.net-core-mvc antiforgerytoken

当我将表单发布到具有"授权"的HttpPost控制器方法时属性,它失败了,我收到了一个错误的请求。如果我删除" ValidateAntiForgeryToken"从方法属性,它工作正常!这是正常行为吗?

我的创业公司:

        public void ConfigureServices(IServiceCollection services)
    {
        try
        {
            services.AddAuthentication(CookieAuthenticationDefaults.AuthenticationScheme)
                .AddCookie(CookieAuthenticationDefaults.AuthenticationScheme, options =>
                {
                    options.ExpireTimeSpan = new TimeSpan(90, 0, 0, 0);
                    options.LoginPath = new PathString("/Home/Index/");
                    options.AccessDeniedPath = new PathString("/Home/Index/");
                    options.LogoutPath = new PathString("/Home/Index/");
                    options.Validate();
                });

            services.AddMvc();
            services.AddAntiforgery();
            services.Configure<MvcOptions>(options =>
            {
                options.Filters.Add(new RequireHttpsAttribute());
            });
        }
        catch (Exception ex)
        {
            gFunc.ProcessError(ex);
        }
    }

Controller SignIn:

        // create claims
        var claims = new List<Claim>
        {
            new Claim(ClaimTypes.Name, c_signed_in.FirstName + gFunc.SPACE + c_signed_in.FamilyName),
            new Claim(ClaimTypes.Email, c_signed_in.Email),
            // new Claim(ClaimTypes.SerialNumber, c_signed_in.AccountPassword)
        };

        // create identity
        var identity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme); // cookie or local

        // create principal
        ClaimsPrincipal principal = new ClaimsPrincipal(new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme));

        // sign-in
        await HttpContext.SignInAsync(scheme: CookieAuthenticationDefaults.AuthenticationScheme, principal: principal);

我的控制器:

    [HttpPost]        
    [Authorize]
    [ValidateAntiForgeryToken]

我的观点:

    <form class="form-group" asp-controller="Home" asp-action="SubmitAccountForm" enctype="multipart/form-data" method="post">

    @Html.AntiForgeryToken()

    @*code here*@

    <div class="text-center">
        <button class="btn btn-primary" type="submit">Submit</button>
    </div>

</form>

3 个答案:

答案 0 :(得分:1)

我相信您的最后一步是让您的应用程序在HTTP请求管道中创建XSRF令牌。此时,您的应用程序被告知要对XSRF进行验证,但没有令牌插入到服务器进行比较的请求中。

在你的Startup.cs中,添加 IAntiforgery antiforgery 参数,然后添加 XSRF config 块。

public void Configure(IApplicationBuilder app, IHostingEnvironment env, IAntiforgery antiforgery)
    {
        // XSRF config
        app.Use(next => context =>
        {
            string path = context.Request.Path.Value;

            if (
                string.Equals(path, "/", StringComparison.OrdinalIgnoreCase) ||
                path.StartsWith("/Login",StringComparison.OrdinalIgnoreCase))
            {
                // The request token can be sent as a JavaScript-readable cookie, 
                // and Angular uses it by default.
                var tokens = antiforgery.GetAndStoreTokens(context);
                context.Response.Cookies.Append("XSRF-TOKEN", tokens.RequestToken,
                                                new CookieOptions() { HttpOnly = false });
            }

            return next(context);
        });
        // End XSRF config

...

注意:IF语句只控制为其创建XSRF令牌的请求路径。您只需确保在需要之前创建它。

(我添加了&#34; / Login&#34; case,因为当用户注销时,他们仍然在我的应用程序中的/ Login路径,我需要刷新XSRF令牌才能再次尝试登录。 )

Configure antiforgery features with IAntiforgery

答案 1 :(得分:0)

新表单标记助手输出防伪标记作为from的一部分。 (见以下) https://docs.microsoft.com/en-us/aspnet/core/mvc/views/working-with-forms

所以也许这样试试(编辑后显示缺失的代码)

  <form class="form-group" asp-controller="Home" asp-action="SubmitAccountForm" enctype="multipart/form-data" method="post">



    @*code here*@

    <div class="text-center">
        <button class="btn btn-primary" type="submit">Submit</button>
    </div>

</form>

答案 2 :(得分:0)

我花了一些时间钻研ASP.NET MVC,还买了一本我推荐的优秀书:&#34; Pro ASP.NET Core MVC 2&#34;由弗里曼。经过大量挖掘后,您似乎无法将Post方法中的[ValidateAntiForgeryToken]属性与[Authorize]属性一起使用。它会引发异常。我想如果它被授权,则无需验证令牌。