asp.net 核心中的 csp 报告端点
csp-report endpoint in asp.net core
我正在尝试在 asp.net 核心网络应用程序中设置 CSP,并且 CSP 部分工作正常,我可以在浏览器控制台中看到违规行为,因为它们被发送到 report-uri 端点。
但是,我似乎无法在控制器中创建正确的方法来接收这些消息!
我在控制器中创建了一个方法:
[HttpPost]
[AllowAnonymous]
public IActionResult UriReport(CspReportRequest request)
{
_log.LogError("CSP violation: " + request);
return Ok();
}
它会被调用,但是'request'参数总是空的。一些搜索显示我需要使用 [FromBody] 属性从正文中读取数据,但是一旦我把它放进去,它就不再被调用了。
(CspReportRequest 是一个 class,其属性与 csp-report 负载相匹配,但它也不适用于字符串类型。)
所以进一步阅读建议我为正文发送的 'application/csp-report' 内容类型添加一个处理程序:
services.Configure<MvcOptions>(options => {
options.InputFormatters.OfType<JsonInputFormatter>().First().SupportedMediaTypes.Add(
new MediaTypeHeaderValue("application/csp-report"));
});
但这似乎并没有什么不同。
那么 - 我如何制作正确的控制器签名,and/or 正确的服务处理程序选项来接收数据。
完成这项工作需要两件事。第一个是将 [FromBody]
添加到您的 CspReportRequest request
参数1:
public IActionResult UriReport([FromBody] CspReportRequest request)
没有[FromBody]
,JsonInputFormatter
将不会用于解析请求正文。但是,和 [FromBody]
,您将开始看到 415
回复。
第二件事是配置 JsonInputFormatter
以支持 application/csp-report
媒体类型,您已经尝试这样做了。您的方法的问题是实际上配置了 两个 个 JsonInputFormatter
实例,而您影响了错误的实例。如果你只是从 First()
更改为 Last()
2,它应该可以工作。
为什么?集合中的第一个 JsonInputFormatter
实际上是 JsonPatchInputFormatter
的一个实例,它扩展了 JsonInputFormatter
:
public class JsonPatchInputFormatter : JsonInputFormatter
这是第一个添加的,所以它就是您要配置的那个。它无法处理 CspReportRequest
的实例,因为它有关于处理 JsonPatchDocument<T>
等的特定规则,所以它传递给第二个 JsonInputFormatter
。正如我所提到的,第二个实例未配置为支持 application/csp-report
,因此它也无法处理请求。
1 如果您使用 [ApiController]
,则不需要使用 [FromBody]
,但您问题中的所有内容都表明您不使用 [ApiController]
.
2 使用 Last()
而不是 First()
不一定是最好的方法,但它应该可以证明问题所在。有很多方法可以获得您感兴趣的特定 JsonInputFormatter
。
我正在尝试在 asp.net 核心网络应用程序中设置 CSP,并且 CSP 部分工作正常,我可以在浏览器控制台中看到违规行为,因为它们被发送到 report-uri 端点。
但是,我似乎无法在控制器中创建正确的方法来接收这些消息!
我在控制器中创建了一个方法:
[HttpPost]
[AllowAnonymous]
public IActionResult UriReport(CspReportRequest request)
{
_log.LogError("CSP violation: " + request);
return Ok();
}
它会被调用,但是'request'参数总是空的。一些搜索显示我需要使用 [FromBody] 属性从正文中读取数据,但是一旦我把它放进去,它就不再被调用了。 (CspReportRequest 是一个 class,其属性与 csp-report 负载相匹配,但它也不适用于字符串类型。)
所以进一步阅读建议我为正文发送的 'application/csp-report' 内容类型添加一个处理程序:
services.Configure<MvcOptions>(options => {
options.InputFormatters.OfType<JsonInputFormatter>().First().SupportedMediaTypes.Add(
new MediaTypeHeaderValue("application/csp-report"));
});
但这似乎并没有什么不同。
那么 - 我如何制作正确的控制器签名,and/or 正确的服务处理程序选项来接收数据。
完成这项工作需要两件事。第一个是将 [FromBody]
添加到您的 CspReportRequest request
参数1:
public IActionResult UriReport([FromBody] CspReportRequest request)
没有[FromBody]
,JsonInputFormatter
将不会用于解析请求正文。但是,和 [FromBody]
,您将开始看到 415
回复。
第二件事是配置 JsonInputFormatter
以支持 application/csp-report
媒体类型,您已经尝试这样做了。您的方法的问题是实际上配置了 两个 个 JsonInputFormatter
实例,而您影响了错误的实例。如果你只是从 First()
更改为 Last()
2,它应该可以工作。
为什么?集合中的第一个 JsonInputFormatter
实际上是 JsonPatchInputFormatter
的一个实例,它扩展了 JsonInputFormatter
:
public class JsonPatchInputFormatter : JsonInputFormatter
这是第一个添加的,所以它就是您要配置的那个。它无法处理 CspReportRequest
的实例,因为它有关于处理 JsonPatchDocument<T>
等的特定规则,所以它传递给第二个 JsonInputFormatter
。正如我所提到的,第二个实例未配置为支持 application/csp-report
,因此它也无法处理请求。
1 如果您使用 [ApiController]
,则不需要使用 [FromBody]
,但您问题中的所有内容都表明您不使用 [ApiController]
.
2 使用 Last()
而不是 First()
不一定是最好的方法,但它应该可以证明问题所在。有很多方法可以获得您感兴趣的特定 JsonInputFormatter
。