【问题标题】:Getting 400 bad request when I use "ValidateAntiForgeryToken" and "Authorize"当我使用“ValidateAntiForgeryToken”和“Authorize”时收到 400 个错误请求
【发布时间】: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 并且它成功验证了伪造令牌。

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

【问题讨论】:

    标签: xamarin asp.net-core-mvc jwt dotnet-httpclient antiforgerytoken


    【解决方案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 错误。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-17
    • 1970-01-01
    相关资源
    最近更新 更多