ASP.NET Core + Antiforgery + jQuery Ajax POST + Nginx - 400 错误请求

ASP.NET Core + Antiforgery + jQuery Ajax POST + Nginx - 400 Bad Request

该主题有很多类似 的问题,但其中 none 解决了我今天面临的具体问题。

受影响的环境是:

使用 jQuery 发出 Ajax POST 时会出现此问题(其他 JS 框架也会失败),会出现 400 - 由于 Antiforgerytoken 未被正确验证而导致的错误请求.

此问题与缺少防伪令牌无关,因为它已正确添加到 Ajax 调用 header 字段 and/or以适当的方式形成字段:

@inject IAntiforgery antiforgery 
@{
    var tokenSet = antiforgery.GetAndStoreTokens(Context);
}

[...]

$.ajax({
    headers: {
        "@tokenSet.HeaderName": "@tokenSet.RequestToken"
    },
    data: {
        "@tokenSet.FormFieldName": "@tokenSet.RequestToken"
    },

    [...]

});

上述设置防伪令牌的模式被证明工作正常,以至于当直接访问 Kestrel 时调用在开发中甚至在生产中都被接受(如果不涉及 Nginx 则不会出现 400 错误)。

事实上,这个问题似乎与这个特定的 Nginx 问题有关:

在第一个线程中还有一个解决方法,它依赖于以下 Nginx 设置:

proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $http_connection;

不幸的是,建议的解决方法对我不起作用。

有什么线索吗?


更新:我最终设法解决了这个问题。问题与我在 header 名称和 cookie 名称中的一个点有关:

services.AddAntiforgery(options => {
    options.Cookie.Name = "X-CSRF-TOKEN-MyApp.Namespace";
    options.HeaderName = "X-CSRF-TOKEN-MyApp.Namespace";
});

足以摧毁一切。感谢 Mike Bogolepov 的回答,问题不是他建议的下划线,但该建议仍然足以为我指明正确的方向:谢谢!

根据我遇到同样问题的经验,我想假设:

首先,您的应用程序是否使用 Aspnet Core DataProtection? https://docs.microsoft.com/en-us/aspnet/core/security/data-protection/introduction?view=aspnetcore-3.1。错误的验证可能与它有关。

其次,我们有一个带下划线的 header 并且 nginx 将其从请求切到 Kestrel。 http://nginx.org/en/docs/http/ngx_http_core_module.html#underscores_in_headers. If you use k8s with ingress in your production: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#enable-underscores-in-headers.

您是否覆盖 header 名称或在 Startup.cs(AddAntiforgery() 方法)中将其置空?