0

我读到 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>
4

0 回答 0