全部产品

发送 HTTP 请求(C# )

本文介绍 API 订阅方应用如何使用 C# 语言对 HTTP 请求加签、验签。 API 网关提供了 C# SDK,即 mosng-sdk-csharp.zip。该 SDK 集成了加签、验签的逻辑,同时默认支持序列化和反序列化。

前提条件

在进行本地应用开发前,您需要确保已经完成以下操作:

  • 已在 API 网关控制台创建应用,请参见 创建应用
  • 已将该应用的 APPID 提供给了 API 发布者,并获得了授权,请参见 授权 API
  • 已获取如下服务配置信息。具体获取方法,请参见 获取服务端信息
    • 应用的访问密钥(Access Key/Secret Key)
    • API 的域名地址(host)、请求路径(path)、方法(method)、请求体(body)

操作步骤

  1. 获取并安装 Visual Studio,可至 Visual Studio 官方网站 下载。

  2. 引入 C# SDK。

    1. 下载 SDK 及二进制文件 mosng-sdk-csharp.zipHttpSignatures.dll.zip

    2. 解压 mosng-sdk-csharp.zip 进入对应的目录后,双击 SDK 包 signature.sln 文件,将 C# SDK 引入 Visual Studio。

      其中,HttpSignatures 项目为实现签名算法的共享库,可用于.Net Framework.Net Core 项目。HttpSignatureTests 项目为调用示例。

  3. 定义要加签的 headers 和算法。

    1. var spec = new SignatureSpecification(){
    2. Algorithm = "hmac-sha256",
    3. Headers = new string[] { "content-length", "host", "date", "(request-target)" },
    4. KeyId = keyId
    5. };
  4. 构建 request 对象。 您需要构建 request 对象,用于组装请求,代码示例如下:

    1. var request = new Request();
    2. request.Path = "/foo/Bar";
    3. request.Method = HttpMethod.Get;
    4. request.SetHeader("content-length", "18");
    5. request.SetHeader("host", "example.org");
    6. request.SetHeader("date", "Tue, 07 Jun 2014 20:51:35 GMT");
  5. 构建一个 signer 对象。

    AuthorizationParser 对象包含 hmac-sha1、hmac-sha256、hmac-sha512 三种算法。HttpSignatureStringExtractor 对象初始化,用来加签 request 请求 header 中的字段。

    代码示例如下:

    1. var signer = new HttpSigner(new AuthorizationParser(), new HttpSignatureStringExtractor());
    2. signer.Sign(request, spec, keyId, privateKey);
  6. 签名计算。

    计算签名之后,签名信息放在 request 的 header[“Signature”] 里。

    代码示例如下:

    1. var signer = new HttpSigner(new AuthorizationParser(), new HttpSignatureStringExtractor());
    2. signer.Sign(request, spec, keyId, privateKey);
  7. 签名验证。

    取出 request 的 header[“Signature”] 里的加签信息并查询验证结果。

    代码示例如下:

    1. string s = signer.CalculateSignature(request, spec, privateKey);
    2. Console.WriteLine(s);
    3. Assert.AreEqual("yT/NrPI9mKB5R7FTLRyFWvB+QLQOEAvbGmauC0tI+Jg=", s);

完整样例

  1. [Test]
  2. public void SignRequestTest2()
  3. {
  4. String authorization = "Signature keyId=\"hmac-key-1\",algorithm=\"hmac-sha256\",headers=\"content-length host date (request-target)\",signature=\"yT/NrPI9mKB5R7FTLRyFWvB+QLQOEAvbGmauC0tI+Jg=\"";
  5. String keyId = "hmac-key-1"; // accessKey
  6. String privateKey = "don't tell"; // secretKey
  7. // 定义要加签的headers和算法
  8. var spec = new SignatureSpecification()
  9. {
  10. Algorithm = "hmac-sha256",
  11. Headers = new string[] { "content-length", "host", "date", "(request-target)" },
  12. KeyId = keyId
  13. };
  14. // http 请求
  15. var request = new Request();
  16. request.Path = "/foo/Bar";
  17. request.Method = HttpMethod.Get;
  18. request.SetHeader("content-length", "18");
  19. request.SetHeader("host", "example.org");
  20. request.SetHeader("date", "Tue, 07 Jun 2014 20:51:35 GMT");
  21. // 签名计算,计算之后,签名信息放在request的 header["Signature"] 里
  22. var signer = new HttpSigner(new AuthorizationParser(), new HttpSignatureStringExtractor());
  23. signer.Sign(request, spec, keyId, privateKey);
  24. Console.WriteLine(request.GetHeader("Signature"));
  25. Assert.AreEqual(authorization, request.GetHeader("Signature"));
  26. // 独立的签名计算方法
  27. string s = signer.CalculateSignature(request, spec, privateKey);
  28. Console.WriteLine(s);
  29. Assert.AreEqual("yT/NrPI9mKB5R7FTLRyFWvB+QLQOEAvbGmauC0tI+Jg=", s);
  30. }

加签算法

  1. Base64(hmac-sha256(signing_string, Encoding.UTF8.GetBytes(private_key)))
  2. Base64(hmac-sha512(signing_string, Encoding.UTF8.GetBytes(private_key)))
  3. Base64(hmac-sha1(signing_string, Encoding.UTF8.GetBytes(private_key)))
  • signing_string:加签的字符串,根据 SignatureSpecification 里的 Headers 里定义的头生成。
  • secret_key:私钥,用 UTF-8 编码转成字节数组。

限制说明

目前没有对 HTTP 请求的 body 做摘要(digest)加签。