You need to enable JavaScript to run this app. C#开启HMACAuthentication的PUT接口接收到null参数问题
优惠活动
大模型
产品
解决方案
定价
更多

C#开启HMACAuthentication的PUT接口接收到null参数问题

问题根因及修复方案

这个问题是ASP.NET Web API 2(从你用的IHttpActionResult可判断框架版本)的请求体流特性和HMAC校验逻辑的常见冲突,核心原因如下:

  • 最常见的原因是HMACAuthenticationAttribute在校验签名时提前读取了请求体,且未处理流的复用逻辑。ASP.NET Web API 默认的请求体是仅向前的只读流,只能读取一次:如果你的HMAC校验逻辑为了计算请求内容的哈希值,提前把请求体流读完了,后续模型绑定阶段没有内容可以读取,自然就会把MyDTO obj绑定为null,加[FromBody]也不会生效,因为根本读不到请求内容。
  • 第二种可能是你读取请求体时没有启用内容缓冲,就算尝试重置流位置也会因为流不支持Seek操作失败。

修复方法

修改你的HMACAuthenticationAttribute的校验逻辑,读取请求体前先开启内容缓冲,示例代码如下:

public class HMACAuthenticationAttribute : Attribute, IAuthenticationFilter
{
    public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    {
        // 第一步:先将请求内容加载到内存缓冲,允许重复读取
        await context.Request.Content.LoadIntoBufferAsync();
        
        // 第二步:读取请求体内容计算HMAC哈希
        string requestBody = await context.Request.Content.ReadAsStringAsync();
        string computedSignature = 你的HMAC计算方法(requestBody, 密钥);
        
        // 第三步:执行签名校验逻辑,校验通过才继续执行后续流程
        if (computedSignature != context.Request.Headers.GetValues("你的签名字段").FirstOrDefault())
        {
            context.ErrorResult = new StatusCodeResult(HttpStatusCode.Unauthorized, context.Request);
            return;
        }
        
        // 注意:如果是直接读Stream的方式计算哈希,读完后需要手动把流位置重置为0
        // var stream = await context.Request.Content.ReadAsStreamAsync();
        // // 读流计算哈希的逻辑...
        // stream.Position = 0;
    }

    public Task ChallengeAsync(HttpAuthenticationChallengeContext context, CancellationToken cancellationToken)
    {
        // 你的挑战逻辑
        return Task.CompletedTask;
    }
}

如果修改后还是有问题,可以检查你的HMAC逻辑中是否有替换context.Request.Content对象、修改Content-Type头的操作,这类操作也会导致后续模型绑定失败。

内容的提问来源于stack exchange,提问作者Tawm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.08 09:57:03