Skip to content

Instantly share code, notes, and snippets.

@jriquelme
Created November 29, 2019 15:14
Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jriquelme/d11e0bb2e4523523a4ee507282ba6184 to your computer and use it in GitHub Desktop.
Save jriquelme/d11e0bb2e4523523a4ee507282ba6184 to your computer and use it in GitHub Desktop.
Signing of Elastic requests (https://github.com/elastic/go-elasticsearch) according to AWS v4 Signing process
cfg, err := external.LoadDefaultAWSConfig()
if err != nil {
panic(err)
}
esCfg := elasticsearch.Config{
Transport: &awssigner.V4Signer{
RoundTripper: http.DefaultTransport,
Credentials: cfg.Credentials,
Region: cfg.Region,
},
}
es, err := elasticsearch.NewClient(esCfg)
if err != nil {
panic(err)
}
res, err := es.Search(
es.Search.WithBody(strings.NewReader(`{"query": {"match_all": {}}}`)),
)
if err != nil {
panic(err)
}
b, err := ioutil.ReadAll(res.Body)
if err != nil {
panic(err)
}
log.Printf("response: %s", b)
package awssigner
import (
"bytes"
"fmt"
"io/ioutil"
"net/http"
"time"
"github.com/aws/aws-sdk-go-v2/aws"
v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
)
// V4Signer is a http.RoundTripper implementation to sign requests according to
// https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html. Many libraries allow customizing the behavior
// of HTTP requests, providing a transport. A V4Signer transport can be instantiated as follow:
//
// cfg, err := external.LoadDefaultAWSConfig()
// if err != nil {
// ...
// }
// transport := &V4Signer{
// RoundTripper: http.DefaultTransport,
// Credentials: cfg.Credentials,
// Region: cfg.Region,
// }
type V4Signer struct {
RoundTripper http.RoundTripper
Credentials aws.CredentialsProvider
Region string
}
func (s *V4Signer) RoundTrip(req *http.Request) (*http.Response, error) {
signer := v4.NewSigner(s.Credentials)
switch req.Body {
case nil:
_, err := signer.Sign(req, nil, "es", s.Region, time.Now())
if err != nil {
return nil, fmt.Errorf("error signing request: %w", err)
}
default:
b, err := ioutil.ReadAll(req.Body)
if err != nil {
return nil, err
}
_, err = signer.Sign(req, bytes.NewReader(b), "es", s.Region, time.Now())
if err != nil {
return nil, fmt.Errorf("error signing request: %w", err)
}
req.Body = ioutil.NopCloser(bytes.NewReader(b))
}
return s.RoundTripper.RoundTrip(req)
}
@alimoeeny
Copy link

Thanks a lot, works perfectly.

@jriquelme
Copy link
Author

This isn't working with aws-sdk-go-v2 v0.22.0 (Sign was deprecated and now has a ctx parameter). I left an updated example in https://github.com/jriquelme/awsgosigv4.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment