当我使用“ValidateAntiForgeryToken”和“Authorize”时收到 400 个错误请求

Posted

技术标签:

【中文标题】当我使用“ValidateAntiForgeryToken”和“Authorize”时收到 400 个错误请求【英文标题】:Getting 400 bad request when I use "ValidateAntiForgeryToken" and "Authorize" 【发布时间】:2017-05-28 22:21:22 【问题描述】:

我在服务器端使用 asp.net core,在客户端使用 xamarin。我使用 JWT 令牌,我想同时验证伪造令牌。

这是我的客户端代码:

 public async Task<string> PostAsync(object model, string url)
        
            var cookieContainer = new CookieContainer();
            var handlerhttps = new HttpClientHandler
            
                UseCookies = true,
                UseDefaultCredentials = true,
                CookieContainer = cookieContainer
            ;

            var clientPage = new HttpClient(handler: handlerhttps)
            
                BaseAddress = new Uri(uriString: Application.Current.Resources[index: "Domain"] + "/api/token")
            ;

            var pageWithToken = await clientPage.GetAsync(requestUri: clientPage.BaseAddress);
            var verificationToken = await pageWithToken.Content.ReadAsStringAsync();
            using (var handler = new HttpClientHandler
            
                CookieContainer = cookieContainer,
                UseDefaultCredentials = true,
                UseCookies = true
            )
            
                using (var client = new HttpClient(handler: handler) BaseAddress = new Uri(uriString: url))
                
                    client.DefaultRequestHeaders.Add(name: "RequestVerificationToken", value: verificationToken);
                    if (Application.Current.Properties[key: "Token"] != null)
                    
                        var token = Application.Current.Properties[key: "Token"].ToString();
                        client.DefaultRequestHeaders.Authorization =
                            new AuthenticationHeaderValue(scheme: "Bearer", parameter: token);
                    


                    var json = JsonConvert.SerializeObject(value: model);
                    var content = new StringContent(content: json, encoding: Encoding.UTF8,
                        mediaType: "application/json");
                    var response = await client.PostAsync(requestUri: client.BaseAddress, content: content);
                    var result = await response.Content.ReadAsStringAsync();
                    return result;
                
            
         

我的问题是当我在服务器端同时使用[ValidateAntiForgeryToken][Authorize] 时,我收到了 400 错误请求。

但是当我删除[ValidateAntiForgeryToken]时,它会毫无问题地授权。

当我删除 [Authorize] 时,我没有收到 400 bad request 并且它成功验证了伪造令牌。

我不知道如何解决这个问题。

【问题讨论】:

【参考方案1】:

如果您使用Microsoft.AspNetCore.Mvc.TagHelpers,它将添加一个带有“难以猜测”代码的输入字段:

<input name="__RequestVerificationToken" type="hidden" value="CfDJ8PXv-VNSuRBLvOlUgHlQcf4p8B29vW6EKn4ENesSgHR79kWTvbnQ9a1Taj90b-e66-79H7Nx5ljHnvPbwqfSNqHMRMaBkoRKGsTxtbZZlq0rSl2zbGK2aKpPQc0qnoNuRehSNhP097P5-Vlp-3OSPYdIqLQJSqIsPDaQsEOXsNU4qIIDrj-tIhqk5EW9tTYc6g">

无论如何,即使您添加@html.AntiForgeryToken() 也不会冲突。但是,您不能使用 [ValidateAntiForgeryToken] 装饰“第一个”控制器动作,只有最后一个带有 POST 的控制器动作。

例子:

操作 1

[HttpPost]
[AllowAnonymous]
[ActionName("SpecialSignUp")]
public IActionResult Index([FromForm] string email)

    // TODO : code in here
    return View(email);

用户将通过 POST 重定向到上述操作。

假设上面的视图显示了一个表单,其中预先填写了电子邮件字段和要填写的其他字段。

如果你用[ValidateAntiForgeryToken] 装饰它,你会得到一个400(错误请求)。删除它,一切都会好起来的。

动作 2

[HttpPost]
[AllowAnonymous] // It could be [Authorized]
[ActionName("SpecialSignUp")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> LaunchSignUpAsync([FromForm] SpecialSignUpViewModel model)

    // TODO : Code in here
    return RedirectToAction("OtherActionX", data);

表单将由上述视图发布

现在一切正常,不再发生冲突。如果您尊重该顺序,它将对您有用!

我遇到了同样的问题,因为我也用 [ValidateAntiForgeryToken] 装饰了“动作 1”。

希望对您有所帮助!

【讨论】:

我以后会测试你的序列解决方案,谢谢,但我在过去几天搜索了一个问题,我在堆栈中遇到了一个问题,有人问:“我们使用时是否需要使用伪造令牌非 cookie 会话令牌(如 JWT)”,有人回答说:“不,当有人可以访问您的会话令牌时,伪造令牌无助于您的安全并且它无用”。这是真的吗?就是说 ValidateAntiForgeryToken 和 Authorized 一起用,没用,只用 Authorized 就够了。 在 PostAsync 之前还有其他操作吗?就像用户请求的页面会有一个带有“__RequestVerificationToken”的表单?如果没有先生成令牌,您一开始就无法达到那个端点(PostAsync)。 我从服务器端的这个操作中获得验证令牌,就像你在我的问题 Xamarin 代码端看到的一样,我通过标头将它发送到服务器... [HttpGet] public IActionResult ForgeryToken( ) var tokens = _antiforgery.GetAndStoreTokens(httpContext: HttpContext).RequestToken;返回新的对象结果(值:令牌); 【参考方案2】:

我遇到了类似的问题,但通过在我的请求中添加“RequestVerificationToken”解决了它

我的控制器代码(示例)

HttpPost("注销") 授权 ==> 使用 JWT 验证AntiForgeryToken */

【讨论】:

查看我的代码,我还在请求中添加了 RequestVerificationToken,但出现 400 错误。

以上是关于当我使用“ValidateAntiForgeryToken”和“Authorize”时收到 400 个错误请求的主要内容,如果未能解决你的问题,请参考以下文章

为啥在我的 c 程序中,当我使用 double 时它只输出 0,但是当我使用 float 时它可以工作? [复制]

当我访问我的 iframe 时,当我使用 selenium 时,#document 不显示

当我在 ngOnInit() 中使用 router.getCurrentNavigation() 时,它会给我类型错误,但是当我在构造函数中使用它时,它工作正常,为啥?

当我不知道 data.frame 中的列名时,当我使用 dplyr mutate 函数时

Cordova/Phonegap - 当我关闭应用程序时存储一个数组(当我重新打开时使用它们)

为啥当我解构属性时接收道具的组件不起作用,但是当我使用 props.key 时它起作用了?