在Xamarin上使用AntiForgeryToken访问Aspnet 5.0中的WebAPI

22 浏览
0 Comments

在Xamarin上使用AntiForgeryToken访问Aspnet 5.0中的WebAPI

我正在尝试访问一个使用ValidateAntiForgeryToken的WebAPI。我的WebAPI方法如下(一个简单的方法),它位于一个用户控制器中(仅用于测试):\n

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Test(String field)
{
    String result = String.Empty;
    if (ModelState.IsValid)
    {
        HtmlSanitizer sanitizer = new HtmlSanitizer();
        try
        {
            result = sanitizer.Sanitize(field);
        }
        catch (Exception ex)
        {
            result = ex.Message;
            throw;
        }
    }
    return Json(result);
}

\n通过Ajax,我可以轻松访问它:\n

$.ajax({
    url: '/User/Test',
    type: "POST",
    contentType: "application/x-www-form-urlencoded",
    data: {
        field: self.textField(),
        __RequestVerificationToken: $("input[name='__RequestVerificationToken']").val(),
    },
    success: function(e) {
        self.textField(e)
        self.divField(e);
    },
    error: function(e) {
        console.log(e.error());
    },
});

\n但是,到目前为止,我无法使用Xamarin中的HttpClient访问此WebAPI。这是我的代码:\n

private async void DoTestWebApi()
{
    try
    {
        HttpClient clientPage = new HttpClient()
        {
            BaseAddress = new Uri("https://localhost:44356/user")
        };
        var pageWithToken = await clientPage.GetAsync(clientPage.BaseAddress);
        String verificationToken = GetVerificationToken(await pageWithToken.Content.ReadAsStringAsync());
        HttpClient client = new HttpClient()
        {
            BaseAddress = new Uri("https://localhost:44356/user/test/")
        };
        HttpRequestMessage message = new HttpRequestMessage()
        {
            RequestUri = new Uri("https://localhost:44356/user/test/"),
            Method = HttpMethod.Post
        };
        message.Headers.Add("__RequestVerificationToken", verificationToken);
        String field = "teste";
        StringContent content = new StringContent("__RequestVerificationToken=" + verificationToken + ",field=test", Encoding.UTF8, "application/x-www-form-urlencoded");
        var response2 = await client.SendAsync(message);
        if (response2.IsSuccessStatusCode)
        {
            var t = response2.Content.ReadAsStringAsync();
            if (true)
            {
                // just to check if t has value
            }
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
        throw;
    }
}

\n老实说,我不知道还能做什么来在消息中传递我的防伪标记。它在ajax中完美运行,我将其传递给数据内容,但在Xamarin中不起作用。\n所有的代码都在同一台本地主机上执行。如果我删除[ValidateAntiForgeryToken],它可以工作。\n我错过了什么吗?\n编辑:\n好吧,现在我正在使用cookie发送,但它没有再次命中方法。\n这是我的更新:\n

HttpClient clientPage = new HttpClient()
{
    BaseAddress = new Uri("https://localhost:44356/user")
};
var pageWithToken = await clientPage.GetAsync(clientPage.BaseAddress);
String verificationToken = GetVerificationToken(await pageWithToken.Content.ReadAsStringAsync());
List> cookiesInfo = new List>();
foreach (var item in pageWithToken.Headers)
{
    cookiesInfo.Add(new KeyValuePair(item.Key, item.Value.ToString()));
}
cookiesInfo.Add(new KeyValuePair("field", "value"));
cookiesInfo.Add(new KeyValuePair("__RequestVerificationToken", verificationToken));
CookieContainer cookieContainer = new CookieContainer();
using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer })
{
    using (var client = new HttpClient(handler) { BaseAddress = new Uri("https://localhost:44356/user") })
    {
        var content = new FormUrlEncodedContent(cookiesInfo);
        cookieContainer.Add(client.BaseAddress, new Cookie("__RequestVerificationToken", verificationToken));
        foreach (var item in cookiesInfo)
        {
            cookieContainer.Add(client.BaseAddress, new Cookie(item.Key, item.Value));
        }
        var result = client.PostAsync(new Uri("https://localhost:44356/user/test"), content).Result;
        result.EnsureSuccessStatusCode();
    }
};

\n这让我抓狂...好吧,测试是在本地主机上,但很快这个应用程序将在Azure上运行,这是一个先决条件...\n编辑:GetVerificationToken方法:\n

private string GetVerificationToken(String verificationToken)
{
    if (verificationToken != null && verificationToken.Length > 0)
    {
        verificationToken = verificationToken.Substring(verificationToken.IndexOf("__RequestVerificationToken"));
        verificationToken = verificationToken.Substring(verificationToken.IndexOf("value=\"") + 7);
        verificationToken = verificationToken.Substring(0, verificationToken.IndexOf("\""));
    }
    return verificationToken;
}

0
0 Comments

问题出现的原因:

问题是由于作者在使用Aspnet 5.0 on Xamarin进行访问WebAPI时,需要进行身份验证的操作,但是作者没有找到获取防伪令牌(AntiForgeryToken)的方法。

解决方法:

作者补充了获取防伪令牌的方法(GetVerificationToken()),并附上了相关代码。

0
0 Comments

问题:在使用Aspnet 5.0和Xamarin开发中,访问带有AntiForgeryToken的WebAPI时,出现了什么问题?

问题的原因:在发送数据到使用AntiForgeryToken的WebAPI时,缺少了cookie。

解决方法:在访问WebAPI之前,需要获取页面上的AntiForgeryToken,并将其添加到请求中的内容中。同时,需要确保在发送请求时携带了cookie。

具体解决方法如下:

private async void DoTestWebApi()
{
    try
    {
        CookieContainer cookieContainer = new CookieContainer();
        HttpClientHandler handlerhttps = new HttpClientHandler
        {
            UseCookies = true,
            UseDefaultCredentials = true,
            CookieContainer = cookieContainer
        };
        HttpClient clientPage = new HttpClient(handlerhttps)
        {
            BaseAddress = new Uri("https://localhost:44356/user")
        };
        var pageWithToken = await clientPage.GetAsync(clientPage.BaseAddress);
        String verificationToken = GetVerificationToken(await pageWithToken.Content.ReadAsStringAsync());
        var cookies = cookieContainer.GetCookies(new Uri("https://localhost:44356/user"));
        using (var handler = new HttpClientHandler() { CookieContainer = cookieContainer, UseDefaultCredentials = true, UseCookies = true })
        {
            using (var client = new HttpClient(handler) { BaseAddress = new Uri("https://localhost:44356/user/test") })
            {
                var contentToSend = new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair("field", "value"),
                    new KeyValuePair("__RequestVerificationToken", verificationToken),
                });
                var response = client.PostAsync(client.BaseAddress, contentToSend).Result;
            }
        };
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

通过以上代码,可以解决在访问带有AntiForgeryToken的WebAPI时缺少cookie的问题。

0
0 Comments

问题出现的原因是在访问WebAPI时,需要使用AntiForgeryToken来验证请求的合法性。而AntiForgeryToken需要一个名为__RequestVerificationToken的cookie,并且该cookie的值需要与提供的值匹配。这是为了确保提交请求的是浏览表单的用户。

解决方法是在发送请求时,需要同时发送带有正确值的__RequestVerificationToken的cookie。可以使用一些工具,例如Chrome浏览器的Advanced Rest Client,在发送请求时设置正确的cookie,以解决该问题。

0