首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在Xamarin上用AntiForgeryToken访问Aspnet5.0中的AntiForgeryToken

在Xamarin上用AntiForgeryToken访问Aspnet5.0中的AntiForgeryToken
EN

Stack Overflow用户
提问于 2017-02-14 19:59:40
回答 3查看 3.3K关注 0票数 1

我正在尝试访问一个使用WebAPI的ValidateAntiForgeryToken。我的WebAPI方法是这样的(一个简单的方法),它位于用户控制器内(只是为了测试):

代码语言:javascript
复制
[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);
}

使用Ajax,我可以轻松地访问它:

代码语言:javascript
复制
$.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());
    },
});

但是,到目前为止,我还不能在xamarin上使用httpclient访问这个webapi。这是我的密码:

代码语言:javascript
复制
    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("field=test", Encoding.UTF8, "application/x-www-form-urlencoded");
        StringContent content = new StringContent("__RequestVerificationToken=" + verificationToken + ",field=test", Encoding.UTF8, "application/x-www-form-urlencoded");

        // this doesn't work
        //client.DefaultRequestHeaders.Add("__RequestVerificationToken", verificationToken);
        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;
    }

}

老实说,我不知道我还能做些什么才能把我的防伪标记传递到邮件里。它在ajax中很好地工作,我在数据内容中传递它,但是在xamarin中它不工作。所有代码都在同一个本地主机中执行。如果我删除了ValidateAntiForgeryToken,它就能工作。

我遗漏了什么?

编辑:

好的,现在我用cookie发送,但是不会再按这个方法了。这是我的最新消息:

代码语言:javascript
复制
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<KeyValuePair<String, String>> cookiesInfo = new List<KeyValuePair<String, String>>();

foreach (var item in pageWithToken.Headers)
{
    cookiesInfo.Add(new KeyValuePair<String, String>(item.Key, item.Value.ToString()));
}

cookiesInfo.Add(new KeyValuePair<string, string>("field", "value"));
cookiesInfo.Add(new KeyValuePair<string, string>("__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();
    }

};

把我逼疯了..。好的测试是在本地主机,但很快这个应用程序将在Azure,这是一个先决条件.

编辑: GetVerificationToken方法:

代码语言:javascript
复制
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;
    }
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-02-14 23:00:33

ValidateAntiForgeryToken还期待一个带有__RequestVerificationToken和提供的值的cookie。这是为了确保提交给控制器的投递是查看表单的人。

票数 2
EN

Stack Overflow用户

发布于 2017-02-23 04:34:30

多亏了@Zroq提示,我终于做到了。饼干确实不见了。这是我的方法的最后一个版本,它用WebApi MVC 5.0中的AntiForgeryToken将数据发送到Asp.NET:

代码语言:javascript
复制
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<string, string>("field", "value"),
                        new KeyValuePair<string, string>("__RequestVerificationToken", verificationToken),
                    });

                    var response = client.PostAsync(client.BaseAddress, contentToSend).Result;
                }
            };
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

再次感谢@Zroq。

票数 2
EN

Stack Overflow用户

发布于 2017-05-11 08:48:44

对于任何想要GetVerificationToken()主体的人:

代码语言:javascript
复制
private string GetVerification(string responseBody)
{
     var data = QueryHelpers.ParseQuery(queryString: responseBody);
     string firstValue = data[key: "<input name"];
     var cutedValue = firstValue.Remove(startIndex: 0, count: 50);
     var result = cutedValue.Split('"')[0];
     return result;
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42235121

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档