【发布时间】:2021-10-13 19:05:12
【问题描述】:
我有一个自定义的安全处理程序和一个端点。它按预期工作。
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)
{ ... }
现在,我需要检查正文的内容,所以我正在阅读它并分析内容。但是,我注意到通过此添加,不再到达端点。没有例外或任何东西,只是没有命中,就像路线不匹配一样。在调试时,我看到流已用完,因此对流进行断点并再次读取会产生一个空字符串。
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;
}
根据this answer 我应该倒带寻找流的零点,this one 建议也启用缓冲。 (也有建议here,但样本中没有await,这是我的系统必需的,所以我无法正确尝试。)基于此,我登陆了以下内容。
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;
}
现在,返回并重新运行代码确实会再次从流中读取。但是,仍然找不到端点,就像添加上述内容之前一样。但是,如果我从流中删除读数,就会达到它,所以我感觉我仍然以某种方式影响身体读数。
【问题讨论】:
-
我不确定,但是您是否尝试过使用 StreamReader overload 使 baseStream 保持打开状态并在使用它设置
Accessor.HttpContext.Request.Body.Position = 0之后将主体流打开并倒带?跨度> -
你能倒带吗?如果这是可能的,我会感到非常惊讶,尤其是对于大型流。它不像服务器会在任何地方缓存它,并且 HTTP 不允许重播消息体。
-
根据链接的答案,应该可以使用
Accessor.HttpContext.Request.EnableBuffering() -
@Neil 看来我可以,尽管只能在处理程序内部。我的流读取了大概 300 字节的正文(甚至不是 1 kb),所以大小应该不是问题。
-
您似乎试图访问“每条”消息正文中的某种授权数据?这听起来很不标准(出于您现在遇到的原因)。这种方法是“最佳”解决方案,还是您应该以不同的方式看待身份验证?标头(X-AUTH-XXX,或授权等)“更容易”。
标签: c# asp.net-core routes stream asp.net-core-3.1