在ASP.NET Core中,内容类型 "applicationcsp-report "的 "415不支持的媒体类型"。

问题描述 投票:5回答:3

我有一个内容安全策略,导致 Chrome 浏览器发布报告,但接收报告的操作却返回 "415 不支持的媒体类型"。我理解这是因为该帖子的内容类型为 "applicationcsp-report"。我如何将其添加为 Core 3.1 中允许的内容类型(基本上就是 json)。

操作

// https://anthonychu.ca/post/aspnet-core-csp/
[HttpPost][Consumes("application/csp-report")]
public IActionResult Report([FromBody] CspReportRequest request)
{
    return Ok();
}

缩小版模型

public class CspReportRequest
{
    [JsonProperty(PropertyName = "csp-report")]
    public CspReport CspReport { get; set; }
}

public class CspReport
{
    [JsonProperty(PropertyName = "document-uri")]
    public string DocumentUri { get; set; }
}
c# asp.net-core asp.net-core-3.1
3个回答
4
投票

下面的示例展示了如何向Chrome浏览器添加支持。SystemTextJsonInputFormatter 用于处理额外的媒体类型。

services.AddControllers(options =>
{
    var jsonInputFormatter = options.InputFormatters
        .OfType<SystemTextJsonInputFormatter>()
        .Single();

    jsonInputFormatter.SupportedMediaTypes.Add("application/csp-report");
});

这是一个两步走的过程。

  1. 查询已配置的输入格式列表,以找到... ... SystemTextJsonInputFormatter.
  2. 增加 application/csp-report 到其现有支持的媒体类型列表中(application/json, text/jsonapplication/*+json).

如果你使用的是Json.NET而不是 System.Text.Json办法是 类似:

services.AddControllers(options =>
{
    var jsonInputFormatter = options.InputFormatters
        .OfType<NewtonsoftJsonInputFormatter>()
        .First();

    jsonInputFormatter.SupportedMediaTypes.Add("application/csp-report");
})

有两个小区别。

  1. 类型是: NewtonsoftJsonInputFormatter 而不是 SystemTextJsonInputFormatter.
  2. 两种 的实例,所以我们将目标放在第一个实例上(见 本回答 具体内容)。)

详见 输入格式 在ASP.NET Core文档中了解更多关于这些的信息。


1
投票

我想补充的是,被接受的解决方案对我不起作用。(.NET Core 3.1)我有一个关于CSP报告的完全相同的用例。当试图使用NewtonSoft并修改InputFormatter时 NewtonsoftJsonInputFormatter 接受媒体头类型 application/csp-report我总是会得到一个异常,说找不到输入格式(不管有没有使用 .AddNewtonsoftJson();)

我通过以下方法解决了这个问题。

services.AddControllers().AddNewtonsoftJson();
services.AddOptions<MvcOptions>()
      .PostConfigure<IOptions<JsonOptions>, IOptions<MvcNewtonsoftJsonOptions>, ArrayPool<char>, ObjectPoolProvider, ILoggerFactory>(
          (mvcOptions, jsonOpts, newtonJsonOpts, charPool, objectPoolProvider, loggerFactory) =>
          {
              var formatter = mvcOptions.InputFormatters.OfType<NewtonsoftJsonInputFormatter>().First(i => i.SupportedMediaTypes.Contains("application/json"));
              formatter.SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/csp-report"));
              mvcOptions.InputFormatters.RemoveType<NewtonsoftJsonInputFormatter>();
              mvcOptions.InputFormatters.Add(formatter);
          });

我的模型和控制器的动作与问题中的相同。

我的解决方案来自于 如何配置两个JSON序列器,并根据路由选择正确的序列器。)


0
投票

上周我也遇到了同样的问题,我找到了一个替代的解决方案,使用我自己的 自定义格式器:

using CspReportLogger.Models;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.Net.Http.Headers;
using System;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;

namespace CspReportLogger.Formatters
{
  public class CSPReportInputFormatter : TextInputFormatter
  {
    public CSPReportInputFormatter()
    {
      // Specify the custom media type.
      SupportedMediaTypes.Add(MediaTypeHeaderValue.Parse("application/csp-report"));
      SupportedEncodings.Add(Encoding.UTF8);
    }

    public override async Task<InputFormatterResult> ReadRequestBodyAsync(InputFormatterContext context, Encoding effectiveEncoding)
    {
      // Deserialize the body using our models and the JsonSerializer.
      CspReportRequest report = await JsonSerializer.DeserializeAsync<CspReportRequest>(context.HttpContext.Request.Body);
      return await InputFormatterResult.SuccessAsync(report);
    }
  }
}

当然要在Startup.cs中注册。

    public void ConfigureServices(IServiceCollection services)
    {
      services.AddControllers(options =>
      {
        options.InputFormatters.Insert(0, new CSPReportInputFormatter());
      });
    }

我希望我已经看到 Kirk Larkin的解决方案 因为它显然更简洁。

我想,如果你想接受不是有效的json的body类型,不过自定义formatter的解决方案是有帮助的。

© www.soinside.com 2019 - 2024. All rights reserved.