简体   繁体   中英

How to create presigned URL for aws gateway API

I have seen pre-signed URL for S3 object. Is it possible to create pre-signed URL for API gateway. I have gone through documentation . I am using .NET. I would like to know if there is .NET library available to create pre-signed request for gateway API.

ISSUE
I have GET API something like this https://xxxxxx.execute-api.us-east-1.amazonaws.com/dev/pets?type=dog&page=1 and our client is going to invoke that API once in a while. The legacy tool that they are using only supports GET . So i wanted to create a pre-signed URL (with short expiry time) and give them when they ask for it. For each client i already have IAM user with their respective accesskey and secretkey

PreSigned URLs are typically signed with AWS SigV4 signing process.

You can generate SigV4 signed Urls for your API Gateway Hosted Endpoints. Typically, you will need to send SigV4 signature in Authorization Request Header. If you are clients are willing to send header, here is one sample Library you can try for .NET which creates a HTTP Request with signed header.

If your clients cannot send Authorization Header or cannot use above library then you can convert the signature to be a Query String Format and provide the pre-signed Urls to them.

This AWS Documentation has example in Python on how to generate Query String URL. Now, you can take python example and convert into .NET based code with following sample.

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

Full Endpoint Becomes -

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

Note -

  1. This example code refers methods & variables from Github project I gave above.
  2. Also, this example hard coded API Path /dev/myApigNodeJS and signs it and it will be different for you with full absolute path.
  3. AWS recommends to sign all queryStrings, headers which you are planning to send in request. Go through .NET code of library I referred and understand how its doing that.

Let me know if you have questions.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM