我读到XSRF为Razor Pages(Core 2.0)提供了"automatically"并开始想知道它走了多远,所以我针对Razor Pages处理程序创建了一个简单的XHR GET 的小型测试 . 令我惊讶的是,它起作用了,但仔细检查 Headers 后就没有任何XSRF了 . 最后我得出结论"automatic"仅适用于形式后场景 .

然后,我尝试通过添加 [ValidateAntiForgeryToken] 属性强制XSRF失败,但它没有任何效果 . 根本不更改客户端代码,并且不向cshtml添加 @Html.AntiForgeryToken() ,该方法仍然运行并返回数据 .

在有人说它对 HTTP GET 无效之前(我已经看到了旧版MVC问题的答案,说明XSRF只适用于表格帖子),this document表示:

ValidateAntiForgeryToken属性需要一个令牌来处理它所装饰的操作方法的请求,包括HTTP GET请求 .

该属性不应该响应错误吗?我是否需要在某处使用某种配置魔法才能使其工作?

此示例的工作原理是将新的“Test”Razor页面添加到ASP.NET Core 2.0 Web App模板项目中,其中包含以下内容 .

Test.cshtml.cs:

public class TestModel : PageModel
{
    public void OnGet() { }

    [ValidateAntiForgeryToken]
    public JsonResult OnGetMySecretData() => 
        new JsonResult("requested super-secret data");
}

Test.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" />

<div id="message"></div>