如何使用Golang客户端调用带有IAM授权的API Gateway端点

huangapple go评论85阅读模式
英文:

How to : Invoke API Gateway endpoint with IAM authorization using golang client

问题

似乎很简单,但我还没有弄清楚。

在下面的代码中 -

resp, err := http.Get("API Gateway endpoint url goes here")
if err != nil {
   log.Fatalln(err)
}

我不确定如何告诉http.get使用AWS身份验证。aws cli已在主机上配置了访问密钥和密钥。所以我不想在代码中再次提及。

一些帖子提到了签署请求。但我不确定这是否是正确的方法。考虑到golang中的AWS SDK,这感觉有点底层。我期望:

  1. AWS SDK中一定有一种方式来封装签署HTTP请求等操作并完成工作
  2. 通过“某种方式”使用内置的http包来完成这个操作

非常感谢任何帮助!

谢谢
Sandeep

英文:

It seems pretty straight forward, but I am not able to figure out yet.

In the code such as below -

resp, err := http.Get("API Gateway endpoint url goes here")
if err != nil {
   log.Fatalln(err)
}

I am not sure how I tell http.get to use AWS auth. aws cli is configured the access key and secret on the host. So I do not want to again mention in the code.

Some posts mentioned about signing request. But I am not sure if that's the right way. In light of the AWS SDK in golang, this feels bit low level stuff.
I would expect either

  1. There must a way in AWS SDK that encapsulates signing HTTP request etc. and does the job
  2. There must be a way to do this using http inbuild package by "somehow" attaching aws creds.

Any help is much, much appreciated!

Thanks
Sandeep

答案1

得分: 1

一些帖子提到了签名请求,但我不确定是否是正确的方法。

是的,IAM Auth需要请求签名(请参阅文档这里这里)。当前的方法是Signature v4。Api Gateway接受请求如果它具有预期的头部。"Signing"是添加正确头部的过程:

# signature is derived from your secret key and the request contents.
--header 'Authorization: AWS4-HMAC-SHA256 Credential=AKIASIAXTWO8D5GSN4CS/20220712/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date, Signature=f2d8478ceff83d5cd0696502cb58a8331304846d11367d74608295c7acbfba0c'
# date prevents third parties from intercepting your request and resubmitting it later
--header 'X-Amz-Date: 20220712T124302Z'

肯定有一种方式在AWS SDK中封装签名HTTP请求等,并完成工作。

对于几种语言(JS、Java等,但不包括Go),get-sdk命令可以为您的Rest API生成SDK客户端,其中包括其他便利功能,包括封装签名过程:client.privateGet(params, body, additionalParams)

肯定有一种方法可以使用内置的http包通过"某种方式"附加AWS凭证来实现这一点。

使用普通的SDK需要更多的工作来添加头部,可以轻松地封装在可重用的类型中:

ctx := context.TODO()

// define the request
endpoint := "https://cbi3vltq21.execute-api.us-east-1.amazonaws.com"
u, _ := url.ParseRequestURI(endpoint)
u.Path = "prod/private"
req, _ := http.NewRequest("GET", u.String(), nil)

// get the credentials from the local config files
cfg, _ := config.LoadDefaultConfig(ctx,
  config.WithRegion("us-east-1"),
  config.WithSharedConfigProfile("my-profile"))
creds, _ :=  cfg.Credentials.Retrieve(ctx) 

// hash the request body - hex value used in the signature
hash := sha256.Sum256([]byte("")) // if the request has no body, use the empty string
hexHash := fmt.Sprintf("%x", hash)

// add the Authorization and X-Amz-Date headers to the request
signer := v4.NewSigner()
_ = signer.SignHTTP(ctx, creds, req, hexHash, "execute-api", cfg.Region, time.Now())

// execute the request
client := &http.Client{}
resp, _ := client.Do(req)

感谢这个SO答案

英文:

> Some posts mentioned signing requests. But I am not sure if that's the right way

Yes, IAM Auth requires request signing (see docs here and here). The current method is Signature v4. Api Gateway accepts a request if it has the expected headers. "Signing" is the process of adding the right headers:

# signature is derived from your secret key and the request contents.
--header 'Authorization: AWS4-HMAC-SHA256 Credential=AKIASIAXTWO8D5GSN4CS/20220712/us-east-1/execute-api/aws4_request, SignedHeaders=host;x-amz-date, Signature=f2d8478ceff83d5cd0696502cb58a8331304846d11367d74608295c7acbfba0c'
# date prevents third parties from intercepting your request and resubmitting it later
--header 'X-Amz-Date: 20220712T124302Z'

> There must a way in AWS SDK that encapsulates signing HTTP request etc. and does the job

For several languages (JS, Java, etc. but not Go), the get-sdk command can generate a SDK client for your Rest API that, among other conveniences, wraps the signature process: client.privateGet(params, body, additionalParams).

> There must be a way to do this using http inbuild package by "somehow" attaching aws creds

Using the plain-old SDKs it's a bit more work to add the headers, easily wrappable in a resusable type:

ctx := context.TODO()

// define the request
endpoint := "https://cbi3vltq21.execute-api.us-east-1.amazonaws.com"
u, _ := url.ParseRequestURI(endpoint)
u.Path = "prod/private"
req, _ := http.NewRequest("GET", u.String(), nil)

// get the credentials from the local config files
cfg, _ := config.LoadDefaultConfig(ctx,
  config.WithRegion("us-east-1"),
  config.WithSharedConfigProfile("my-profile"))
creds, _ :=  cfg.Credentials.Retrieve(ctx) 

// hash the request body - hex value used in the signature
hash := sha256.Sum256([]byte("")) // if the request has no body, use the empty string
hexHash := fmt.Sprintf("%x", hash)

// add the Authorization and X-Amz-Date headers to the request
signer := v4.NewSigner()
_ = signer.SignHTTP(ctx, creds, req, hexHash, "execute-api", cfg.Region, time.Now())

// execute the request
client := &http.Client{}
resp, _ := client.Do(req)

H/T to this SO answer.

huangapple
  • 本文由 发表于 2022年7月5日 19:29:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/72868687.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定