xamarin 使用“ValidateAntiForgeryToken”和“授权”时收到400个错误请求

5rgfhyps  于 2023-01-28  发布在  其他
关注(0)|答案(3)|浏览(160)

我在asp.net服务器端使用www.example.com核心,在客户端使用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个错误请求,它成功验证了伪造令牌。
我不知道如何解决这个问题。

mwkjh3gx

mwkjh3gx1#

如果您使用的是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"。
希望能有所帮助!

jdg4fx2g

jdg4fx2g2#

我也遇到过类似的问题,但通过在请求中添加“RequestVerificationToken”解决了这个问题
我的控制器代码(示例)
HttpPost(“注销”)授权==〉使用JWT验证防伪令牌 */

biswetbf

biswetbf3#

您可以尝试创建一个用于验证JWT标记的自定义方法,将**[Authorize]**替换为

public void ValidateJWT(string token, out bool status)
    {
        if (token == null)
        {
            status = false;
        }

        byte[] secretKey = System.Text.Encoding.UTF8.GetBytes("your jwt secret key");
        var tokenHandler = new JwtSecurityTokenHandler();

        try
        {
            tokenHandler.ValidateToken(token, new TokenValidationParameters
            {
                ValidateIssuerSigningKey = true,
                IssuerSigningKey = new SymmetricSecurityKey(secretKey),
                ValidateIssuer = false,
                ValidateAudience = false,
                ClockSkew = TimeSpan.Zero
            }, out SecurityToken validatedToken);
            status = true;
        }
        catch
        {
            status = false;
        }
    }

相关问题