如何为AWS Gateway API创建预签名URL

时间:2019-01-03 20:47:14

标签: amazon-web-services aws-sdk aws-api-gateway

我已经看到了S3对象的预签名URL。是否可以为API网关创建预签名的URL。我经历了documentation。我正在使用.NET。我想知道是否有.NET库可用于创建网关API的预签名请求。

问题
我有GET这样的https://xxxxxx.execute-api.us-east-1.amazonaws.com/dev/pets?type=dog&page=1 API,我们的客户有时会调用该API。他们使用的旧版工具仅支持GET。所以我想创建一个预签名的URL(有效期短),并在他们要求时给他们。对于每个客户,我已经拥有IAM个用户,分别具有accesskeysecretkey

2 个答案:

答案 0 :(得分:1)

预先签名的URL通常使用AWS Airflow签名过程进行签名。

您可以为SigV4托管端点生成SigV4签名的Urls。通常,您需要在授权请求标头中发送SigV4签名。如果您愿意发送标头,API Gateway是一个示例库,您可以尝试使用.NET创建带有签名标头的HTTP请求。

如果您的客户端无法发送授权标头或无法使用上述库,则可以将签名转换为查询字符串格式,并向其提供预签名的Urls。

here AWS文档在Python中提供了有关如何生成查询字符串URL的示例。现在,您可以使用python示例,并使用以下示例将其转换为基于.NET的代码。

public string GetSig4QueryString(string host, string service, string region)
    {
        var t = DateTimeOffset.UtcNow;
        var amzdate = t.ToString("yyyyMMddTHHmmssZ");
        var datestamp = t.ToString("yyyyMMdd");

        var canonical_uri = "/dev/myApigNodeJS";

        var canonical_headers = "host:" + host+"\n";

        var signed_headers = "host";

        var credential_scope = $"{datestamp}/{region}/{service}/aws4_request";

        var canonical_querystring = "X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=" + WebUtility.UrlEncode(_access_key + "/" + credential_scope)
        + "&X-Amz-Date=" + amzdate + "&X-Amz-SignedHeaders=" + signed_headers;

        Console.WriteLine("canonical_querystring");
        Console.WriteLine(canonical_querystring);

        var payload_hash = Hash(new byte[0]);//No Payload for GET
        var canonical_request = new StringBuilder();
        canonical_request.Append("GET\n");
        canonical_request.Append(canonical_uri + "\n");
        canonical_request.Append(canonical_querystring + "\n");
        canonical_request.Append(canonical_headers + "\n");
        canonical_request.Append(signed_headers + "\n");
        canonical_request.Append(payload_hash);

        Console.WriteLine("canonical_request");
        Console.WriteLine(canonical_request);

        var string_to_sign = $"{algorithm}\n{amzdate}\n{credential_scope}\n" + Hash(Encoding.UTF8.GetBytes(canonical_request.ToString()));

        Console.WriteLine("string_to_sign");
        Console.WriteLine(string_to_sign);

        var signing_key = GetSignatureKey(_secret_key, datestamp, region, service);
        var signature = ToHexString(HmacSHA256(signing_key, string_to_sign));

        var signed_querystring = canonical_querystring+"&X-Amz-Signature=" + signature;

        return signed_querystring;
    }

GetSig4QueryString("myApiId.execute-api.us-east-1.amazonaws.com","execute-api","us-east-1");
//Returned String --> X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential= AKIAIOSFODNN7EXAMPLE%2F20190104%2Fus-east-1%2Fexecute-api%2Faws4_request&X-Amz-Date=20190104T190309Z&X-Amz-SignedHeaders=host&X-Amz-Signature=7b830fce28f7800b3879a25850950f6c4247dfdc07775b6952295fa2fff03f7f

完整端点成为-

  

This

注意-

  1. 此示例代码引用了我在上面给出的https://myApiId.execute-api.us-east-1.amazonaws.com/dev/myApigNodeJS?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=AKIAIOSFODNN7EXAMPLE%2F20190104%2Fus-east-1%2Fexecute-api%2Faws4_request&X-Amz-Date=20190104T190309Z&X-Amz-SignedHeaders=host&X-Amz-Signature=7b830fce28f7800b3879a25850950f6c4247dfdc07775b6952295fa2fff03f7f项目中的方法和变量。
  2. 此外,此示例硬编码的API路径/dev/myApigNodeJS并对其进行签名,使用完整的绝对路径对您来说将有所不同。
  3. AWS建议对所有queryStrings(您打算在请求中发送的标头)进行签名。仔细阅读我引用的.NET库代码,并了解它是如何做到的。

让我知道您是否有疑问。

答案 1 :(得分:0)

在 AWS API 网关内生成 websocket 服务的预签名 url 时,我使用了 Imran 的解决方案并添加了所需的“X-Amz-Security-Token”。