Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"415 Unsupported Media Type" for Content-Type "application/csp-report" in ASP.NET Core

I have a content security policy that causes Chrome to post a report, but the action that receives the report returns "415 Unsupported Media Type". I understand this is because the post has a Content-Type of "application/csp-report". How do I add this as a allowed content type in Core 3.1 (its basically just json).

Action

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

Cut down version of model

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

public class CspReport
{
    [JsonProperty(PropertyName = "document-uri")]
    public string DocumentUri { get; set; }
}
like image 626
Brian Avatar asked Jan 19 '20 14:01

Brian


2 Answers

I would like to add that the accepted solution did not work for me. (.NET Core 3.1) I have the exact same use case regarding the CSP reports. When trying to use NewtonSoft and modifying the InputFormatter NewtonsoftJsonInputFormatter to accept media header type application/csp-report, I would always get an exception saying the inputformatter could not be found (with or without .AddNewtonsoftJson();)

I managed to solve the problem by doing the following:

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);
          });

My model and the controller action are the same as the ones posted in the question.

(I derived my solution from How to configure two JSON serializers and select the correct one based on the route)

like image 53
Vincent Rutten Avatar answered Sep 20 '22 11:09

Vincent Rutten


The following example shows how to add support to the SystemTextJsonInputFormatter for handling additional media-types:

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

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

This is a two-step process:

  1. Interrogate the configured list of input-formatters to find the SystemTextJsonInputFormatter.
  2. Add application/csp-report to its existing list of supported media-types (application/json, text/json, and application/*+json).

If you're using Json.NET instead of System.Text.Json, the approach is similar:

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

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

There are two small differences:

  1. The type is NewtonsoftJsonInputFormatter instead of SystemTextJsonInputFormatter.
  2. There are two instances of this type in the collection, so we target the first (see this answer for the specifics).

See Input Formatters in the ASP.NET Core docs to learn more about those.

like image 43
Kirk Larkin Avatar answered Sep 16 '22 11:09

Kirk Larkin