我读到 XSRF 是为 Razor Pages(Core 2.0)“自动”提供的,并开始想知道这有多远,所以我GET
针对 Razor Pages 处理程序创建了一个小型、简单的 XHR 测试。令我惊讶的是,它起作用了,但是在仔细检查标头后,并没有发生任何 XSRF。最终我得出结论,“自动”仅适用于表单发布场景。
然后我尝试通过添加[ValidateAntiForgeryToken]
属性来强制 XSRF 失败,但它没有效果。完全不更改客户端代码,也不添加@Html.AntiForgeryToken()
到 cshtml,该方法仍然运行并返回数据。
在有人说它无效之前HTTP GET
(我已经看到对旧版本 MVC 问题的回答,说明 XSRF仅适用于表单发布),本文档指出:
该
ValidateAntiForgeryToken
属性需要一个令牌来请求它装饰的操作方法,包括HTTP GET
请求。
属性不应该以错误响应吗?我是否需要某种配置魔法来完成这项工作?
此示例通过向 ASP.NET Core 2.0 Web 应用模板项目添加一个新的“测试”Razor 页面并具有以下内容来工作。
测试.cshtml.cs:
public class TestModel : PageModel
{
public void OnGet() { }
[ValidateAntiForgeryToken]
public JsonResult OnGetMySecretData() =>
new JsonResult("requested super-secret data");
}
测试.cshtml:
@page
@model Site.Pages.TestModel
@{
ViewData["Title"] = "Test";
}
<script>
function test() {
xhr = new XMLHttpRequest();
xhr.open("GET", location.origin + "/Test?handler=mysecretdata");
xhr.setRequestHeader("Accept", "application/json");
xhr.onreadystatechange = progress;
xhr.onerror = notOk;
xhr.send()
}
function progress() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
document.querySelector("#message").textContent = JSON.parse(xhr.responseText);
} else {
notOk();
}
}
}
function notOk() {
document.querySelector("#message").textContent = "ERROR " + xhr.responseText + " (" + xhr.status + ": " + xhr.statusText + ")";
}
</script>
<input type="button" onclick="test()" value="Test" />
<br />
<div id="message"></div>