Skip to content

Instantly share code, notes, and snippets.

@hunterhug
Created October 9, 2017 10:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hunterhug/be981417b80278603731974e7f66e08b to your computer and use it in GitHub Desktop.
Save hunterhug/be981417b80278603731974e7f66e08b to your computer and use it in GitHub Desktop.
AWS AuthSignature
```
// Python版本重构
// 定义了一个连接结构体
type ESConnection struct {
mux sync.RWMutex
Client *http.Client
Host string
Auth bool
Aws AwsAuth
}
// 认证的配置
type AwsAuth struct {
AwsID string
AwsKey string
AwsRegion string
AwsService string
}
func (es *ESConnection) MakeRequest(method, Path string, Data []byte) (body []byte, e error) {
// 加锁
es.mux.Lock()
defer es.mux.Unlock()
var request = &http.Request{}
method = strings.ToUpper(method)
if !strings.HasPrefix(Path, "/") {
Path = "/" + Path
}
if Data != nil {
pr := ioutil.NopCloser(bytes.NewReader(Data))
request, _ = http.NewRequest(method, es.Host+Path, pr)
} else {
request, _ = http.NewRequest(method, es.Host+Path, nil)
}
if es.Auth {
// 在此验证
request.ParseForm()
amzdate, authorization_header := AwsAuthSignature(es.Aws, request.URL.Path, method, request.Host, request.Form, Data)
request.Header.Set("host", request.Host)
request.Header.Set("X-Amz-Date", amzdate)
request.Header.Set("Authorization", authorization_header)
}
reesonse, err := es.Client.Do(request)
log.Logger.Debugf("ES: %v '%v'", request.Method, Path)
if err != nil {
return nil, err
}
if reesonse != nil {
defer reesonse.Body.Close()
}
body, e = ioutil.ReadAll(reesonse.Body)
return
}
func AwsAuthSignature(auth AwsAuth, uri, method, host string, query url.Values, data []byte) (amzdate, authorization_header string) {
// 基本配置
access_key := auth.AwsID
secret_key := auth.AwsKey
region := auth.AwsRegion
service := auth.AwsService
request_parameters := ""
// 查询字符串排序
if query != nil {
temp := []string{}
for k, _ := range query {
temp = append(temp, k)
}
sort.Strings(temp)
temp1 := []string{}
for _, v := range temp {
temp1 = append(temp1, v+"="+url.QueryEscape(query.Get(v)))
}
request_parameters = strings.Join(temp1, "&")
fmt.Println(request_parameters)
}
// 现在时间
now := time.Now().UTC()
amzdate = now.Format("20060102T150405Z")
datestamp := now.Format("20060102")
canonical_uri := uri
canonical_querystring := request_parameters
canonical_headers := "host:" + host + "\n" + "x-amz-date:" + amzdate + "\n"
signed_headers := "host;x-amz-date"
payload_hash := hex.EncodeToString(getSha256Code(""))
if data != nil {
payload_hash = hex.EncodeToString(getSha256Code(string(data)))
}
canonical_request := method + "\n" + canonical_uri + "\n" + canonical_querystring + "\n" + canonical_headers + "\n" + signed_headers + "\n" + payload_hash
algorithm := "AWS4-HMAC-SHA256"
credential_scope := datestamp + "/" + region + "/" + service + "/" + "aws4_request"
string_to_sign := algorithm + "\n" + amzdate + "\n" + credential_scope + "\n" + hex.EncodeToString(getSha256Code(canonical_request))
signing_key := GetSignatureKey(secret_key, datestamp, region, service)
signature := hex.EncodeToString(Sign(signing_key, []byte(string_to_sign)))
authorization_header = algorithm + " " + "Credential=" + access_key + "/" + credential_scope + ", " + "SignedHeaders=" + signed_headers + ", " + "Signature=" + signature
return amzdate, authorization_header
}
func Sign(key, msg []byte) []byte {
h := hmac.New(sha256.New, []byte(key))
h.Write([]byte(msg))
return h.Sum(nil)
}
func GetSignatureKey(key, dateStamp, regionName, serviceName string) []byte {
kDate := Sign([]byte("AWS4"+key), []byte(dateStamp))
kRegion := Sign(kDate, []byte(regionName))
kService := Sign(kRegion, []byte(serviceName))
kSigning := Sign(kService, []byte("aws4_request"))
return kSigning
}
func getSha256Code(s string) []byte {
h := sha256.New()
h.Write([]byte(s))
return h.Sum(nil)
}
```
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment