package main
import (
"bytes"
"crypto/hmac"
"crypto/sha1"
"encoding/base64"
"fmt"
"hash"
"io"
"math/rand"
"net/http"
"net/url"
"os"
"sort"
"strings"
"time"
)
// 用于signHeader的字典排序存放容器。
type headerSorter struct {
Keys []string
Vals []string
}
func percentEncode(encode_str string) string {
str := url.QueryEscape(encode_str)
str = strings.Replace(str, "+", "%20", -1)
str = strings.Replace(str, "*", "%2A", -1)
str = strings.Replace(str, "%7E", "~", -1)
return str
}
// 生成签名方法,返回签名的信息
func signParams(method, secret string, query_params map[string]string) string {
temp := query_params
// 对于temp中的值进行url编码处理
for k, v := range temp {
temp[k] = percentEncode(v)
}
hs := newHeaderSorter(temp)
// Sort the temp by the Ascending Order
hs.Sort()
// https://help.aliyun.com/document_detail/28761.html?spm=5176.doc28763.6.238.nDVDmr
// StringToSign=
// HTTPMethod + “&” +
// percentEncode(“/”)[%2F] + ”&” +
// percentEncode(CanonicalizedQueryString)
signStr := method + "&%2F&"
param_str := ""
for i := range hs.Keys {
param_str += "&" + hs.Keys[i] + "=" + hs.Vals[i]
}
fmt.Println(param_str[1:])
signStr += percentEncode(param_str[1:])
fmt.Println("SigStr: " + signStr)
secret_tmp := secret + "&"
h := hmac.New(func() hash.Hash { return sha1.New() }, []byte(secret_tmp))
io.WriteString(h, signStr)
signedStr := base64.StdEncoding.EncodeToString(h.Sum(nil))
return signedStr
}
func GenRandCode() (code string) {
rand.Seed(time.Now().UnixNano())
code = fmt.Sprintf("%010d", rand.Intn(1000000))
return
}
// Additional function for function SignHeader.
func newHeaderSorter(m map[string]string) *headerSorter {
hs := &headerSorter{
Keys: make([]string, 0, len(m)),
Vals: make([]string, 0, len(m)),
}
for k, v := range m {
hs.Keys = append(hs.Keys, k)
hs.Vals = append(hs.Vals, v)
}
return hs
}
// Additional function for function SignHeader.
func (hs *headerSorter) Sort() {
sort.Sort(hs)
}
// Additional function for function SignHeader.
func (hs *headerSorter) Len() int {
return len(hs.Vals)
}
// Additional function for function SignHeader.
func (hs *headerSorter) Less(i, j int) bool {
return bytes.Compare([]byte(hs.Keys[i]), []byte(hs.Keys[j])) < 0
}
// Additional function for function SignHeader.
func (hs *headerSorter) Swap(i, j int) {
hs.Vals[i], hs.Vals[j] = hs.Vals[j], hs.Vals[i]
hs.Keys[i], hs.Keys[j] = hs.Keys[j], hs.Keys[i]
}
func main() {
access_key_id := "eLnfuekdA5YAbE3J"
access_key_secret := "08HNmwNFDS6dL8Y5yVK9VwO1G8t5t8"
role_arn := "acs:ram::10858175:role/image-oss-role"
params := make(map[string]string)
params["SignatureVersion"] = "1.0"
params["Format"] = "JSON"
params["Timestamp"] = (time.Now().UTC()).Format("2006-09-02T15:04:05Z")
params["RoleArn"] = role_arn
params["RoleSessionName"] = "client"
params["AccessKeyId"] = access_key_id
params["SignatureMethod"] = "HMAC-SHA1"
params["Version"] = "2015-04-01"
params["Action"] = "AssumeRole"
params["SignatureNonce"] = GenRandCode() // "571f8fb8-506e-11e5-8e12-b8e8563dc8d2"
params["Signature"] = url.QueryEscape(signParams("GET", access_key_secret, params))
fmt.Println(url.QueryEscape("2016-09-18T13:33:34Z"))
endpoint := "https://sts.aliyuncs.com/?"
params_url := ""
for k, v := range params {
params_url += "&" + k + "=" + v
}
get_url := endpoint + params_url[1:]
fmt.Println(get_url)
resp, err := http.Get(get_url)
if err != nil {
fmt.Println("Error: " + err.Error())
return
}
defer resp.Body.Close()
io.Copy(os.Stdout, resp.Body)
}
返回结果
{
"RequestId":"7FF7EE31-88A5-4F35-BC70-ED1F73F86446",
"AssumedRoleUser":{
"AssumedRoleId":"390215963032524785:client",
"Arn":"acs:ram::10858175:role/image-oss-role/client"
},
"Credentials":{
"AccessKeySecret":"HSJQDb6qv78vAKCa11RqCKgkNNoFn1uuH1Xpf9WTGbVz",
"AccessKeyId":"STS.Hmag16aeJaZHAwSKTPrWYpmxy",
"Expiration":"2016-09-18T08:12:08Z",
"SecurityToken":"CAES6AIIARKAAUmRL0+KVDzPwQgdvtzhk/2N6QQga/0guU8bXZHRTMiwZWVhKg/fIePAST+WnPt7Hwa3y3ej4zYGseKLUZHl3Yhylpaj+pQNplSKlxVyzbOr53FxgsiVVEz8Q9O0Uk6gUSsuPMKjJGD7VO41zbZ3tbbhyhjj1BYkDklgBV3fWyIRGh1TVFMuSG1hZzE2YWVKYVpIQXdTS1RQcldZcG14eSISMzkwMjE1OTYzMDMyNTI0Nzg1KgZjbGllbnQw6PLo4vMqOgZSc2FNRDVCSgoBMRpFCgVBbGxvdxIbCgxBY3Rpb25FcXVhbHMSBkFjdGlvbhoDCgEqEh8KDlJlc291cmNlRXF1YWxzEghSZXNvdXJjZRoDCgEqSggxMDg1ODE3NVIFMjY4NDJaD0Fzc3VtZWRSb2xlVXNlcmAAahIzOTAyMTU5NjMwMzI1MjQ3ODVyDmltYWdlLW9zcy1yb2xleL/dlgU="
}
}
参考