我正在尝试访问一个使用WebAPI的ValidateAntiForgeryToken。我的WebAPI方法是这样的(一个简单的方法),它位于用户控制器内(只是为了测试):
[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,我可以轻松地访问它:
$.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。这是我的密码:
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发送,但是不会再按这个方法了。这是我的最新消息:
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方法:
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;
}发布于 2017-02-14 23:00:33
ValidateAntiForgeryToken还期待一个带有__RequestVerificationToken和提供的值的cookie。这是为了确保提交给控制器的投递是查看表单的人。
发布于 2017-02-23 04:34:30
多亏了@Zroq提示,我终于做到了。饼干确实不见了。这是我的方法的最后一个版本,它用WebApi MVC 5.0中的AntiForgeryToken将数据发送到Asp.NET:
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。
发布于 2017-05-11 08:48:44
对于任何想要GetVerificationToken()主体的人:
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;
}https://stackoverflow.com/questions/42235121
复制相似问题