|
|
package oss
|
|
|
|
|
|
import (
|
|
|
"crypto/hmac"
|
|
|
"crypto/sha1"
|
|
|
"crypto/tls"
|
|
|
"encoding/base64"
|
|
|
"io/ioutil"
|
|
|
"net/http"
|
|
|
"net/url"
|
|
|
"time"
|
|
|
"github.com/aliyun/aliyun-sts-go-sdk/sts"
|
|
|
)
|
|
|
|
|
|
type AliyunStsClient struct {
|
|
|
ChildAccountKeyId string
|
|
|
ChildAccountSecret string
|
|
|
RoleAcs string
|
|
|
type StsCredentials struct {
|
|
|
AccessKeyId string `json:"access_key_id"`
|
|
|
AccessKeySecret string `json:"access_key_secret"`
|
|
|
Expiration int64 `json:"expiration"`
|
|
|
SecurityToken string `json:"security_token"`
|
|
|
}
|
|
|
|
|
|
func NewStsClient(key, secret, roleAcs string) *AliyunStsClient {
|
|
|
return &AliyunStsClient{
|
|
|
ChildAccountKeyId: key,
|
|
|
ChildAccountSecret: secret,
|
|
|
RoleAcs: roleAcs,
|
|
|
}
|
|
|
type AssumedRoleUser struct {
|
|
|
AssumedRoleId string `json:"assumed_role_id"`
|
|
|
Arn string `json:"arn"`
|
|
|
}
|
|
|
|
|
|
func (cli *AliyunStsClient) GenerateSignatureUrl(sessionName, durationSeconds string) (string, error) {
|
|
|
assumeUrl := "SignatureVersion=1.0"
|
|
|
assumeUrl += "&Format=JSON"
|
|
|
assumeUrl += "&Timestamp=" + url.QueryEscape(time.Now().UTC().Format("2006-01-02T15:04:05Z"))
|
|
|
assumeUrl += "&RoleArn=" + url.QueryEscape(cli.RoleAcs)
|
|
|
assumeUrl += "&RoleSessionName=" + sessionName
|
|
|
assumeUrl += "&AccessKeyId=" + cli.ChildAccountKeyId
|
|
|
assumeUrl += "&SignatureMethod=HMAC-SHA1"
|
|
|
assumeUrl += "&Version=2015-04-01"
|
|
|
assumeUrl += "&Action=AssumeRole"
|
|
|
assumeUrl += "&SignatureNonce=" + "TODO"
|
|
|
assumeUrl += "&DurationSeconds=" + durationSeconds
|
|
|
|
|
|
// 解析成V type
|
|
|
signToString, err := url.ParseQuery(assumeUrl)
|
|
|
if err != nil {
|
|
|
return "", err
|
|
|
}
|
|
|
|
|
|
// URL顺序化
|
|
|
result := signToString.Encode()
|
|
|
|
|
|
// 拼接
|
|
|
StringToSign := "GET" + "&" + "%2F" + "&" + url.QueryEscape(result)
|
|
|
|
|
|
// HMAC
|
|
|
hashSign := hmac.New(sha1.New, []byte(cli.ChildAccountSecret+"&"))
|
|
|
hashSign.Write([]byte(StringToSign))
|
|
|
|
|
|
// 生成signature
|
|
|
signature := base64.StdEncoding.EncodeToString(hashSign.Sum(nil))
|
|
|
|
|
|
// Url 添加signature
|
|
|
assumeUrl = "https://sts.aliyuncs.com/?" + assumeUrl + "&Signature=" + url.QueryEscape(signature)
|
|
|
|
|
|
return assumeUrl, nil
|
|
|
type StsData struct {
|
|
|
RequestId string `json:"request_id,omitempty"`
|
|
|
AssumedRoleUser AssumedRoleUser `json:"assumed_role_user,omitempty"`
|
|
|
Credentials StsCredentials `json:"credentials,omitempty"`
|
|
|
}
|
|
|
|
|
|
// 请求构造好的URL,获得授权信息
|
|
|
// 安全认证 HTTPS
|
|
|
func (cli *AliyunStsClient) GetStsResponse(url string) ([]byte, error) {
|
|
|
tr := &http.Transport{
|
|
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
|
|
}
|
|
|
client := &http.Client{Transport: tr}
|
|
|
|
|
|
resp, err := client.Get(url)
|
|
|
func GetStsCredentials() (*StsData, error) {
|
|
|
ossconfig := NewOssConfig()
|
|
|
stsClient := sts.NewClient(ossconfig.accessID, ossconfig.accessKey, ossconfig.roleAcs, ossconfig.sessionName)
|
|
|
resp, err := stsClient.AssumeRole(3600)
|
|
|
if err != nil {
|
|
|
return nil, err
|
|
|
}
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
|
|
|
|
return body, err
|
|
|
c := StsCredentials{
|
|
|
AccessKeyId: resp.Credentials.AccessKeyId,
|
|
|
AccessKeySecret: resp.Credentials.AccessKeySecret,
|
|
|
Expiration: resp.Credentials.Expiration.Unix(),
|
|
|
SecurityToken: resp.Credentials.SecurityToken,
|
|
|
}
|
|
|
ar := AssumedRoleUser{
|
|
|
AssumedRoleId: resp.AssumedRoleUser.AssumedRoleId,
|
|
|
Arn: resp.AssumedRoleUser.Arn,
|
|
|
}
|
|
|
return &StsData{
|
|
|
RequestId: resp.RequestId,
|
|
|
Credentials: c,
|
|
|
AssumedRoleUser: ar,
|
|
|
}, nil
|
|
|
} |
...
|
...
|
|