I have a custom handler for security and an endpoint. It works as supposed to.
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
AwoRequirement requirement)
{
HttpRequest request = Accessor.HttpContext.Request;
string awo = request.Headers
.SingleOrDefault(a => a.Key == "awo").Value.ToString();
...
bools authorized = ...;
if (authorized) context.Succeed(requirement);
else context.Fail();
return Task.CompletedTask;
}
[Authorize(Policy = "SomePolicy"), HttpPost("something")]
public async Task<IActionResult> Something([FromBody] Thing dto)
{ ... }
Now, I need to check the contents of the body, so I'm reading it in and analyze the contents. However, I noticed that with this addition, the endpoint isn't reached anymore. No exception or anything, just simply no hit, like if the route doesn't match. While debugging, I saw that the stream is used up so breakpointing the flow and reading again produces an empty string.
protected override Task HandleRequirementAsync( ... )
{
HttpRequest request = Accessor.HttpContext.Request;
...
using StreamReader stream = new StreamReader(Accessor.HttpContext.Request.Body);
string body = stream.ReadToEndAsync().Result;
Thing thing = JsonSerializer.Deserialize<Thing>(body);
if (thing.IsBad())
authorized &= fail;
...
return Task.CompletedTask;
}
According to this answer I should rewind seeking zero point of the stream, this one suggests enabling of buffering too. (There's also suggestion here but there's no await
in the sample, which is required on my system, so I couldn't try it out properly.) Based on that, I landed in the following.
protected override Task HandleRequirementAsync( ... )
{
HttpRequest request = Accessor.HttpContext.Request;
...
Accessor.HttpContext.Request.EnableBuffering();
using StreamReader stream
= new StreamReader(Accessor.HttpContext.Request.Body);
string body = stream.ReadToEndAsync().Result;
Thing thing = JsonSerializer.Deserialize<Thing>(body);
if (thing.IsBad())
authorized &= fail;
...
return Task.CompletedTask;
}
Now, going back and rerunning the code does read in from the stream again. However, the endpoint isn't found anymore still, just like before adding the above. It is reached if I remove the reading from the stream, though, so I sense that I'm still affecting the body reading somehow.