-
Notifications
You must be signed in to change notification settings - Fork 56
/
Copy pathauth_assumerole.go
86 lines (76 loc) · 2.17 KB
/
auth_assumerole.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package kinesis
import (
"bytes"
"encoding/xml"
"errors"
"fmt"
"net/http"
"net/url"
"time"
)
// NewAuthWithAssumedRole will call STS in a given region to assume a role
// stsAuth object is used to authenticate to STS to fetch temporary credentials
// for the desired role.
func NewAuthWithAssumedRole(roleArn, sessionName, region string, stsAuth Auth) (Auth, error) {
return newCachedMutexedWarmedUpAuth(&stsCreds{
RoleARN: roleArn,
SessionName: sessionName,
Region: region,
STSAuth: stsAuth,
})
}
type stsCreds struct {
RoleARN string
SessionName string
Region string
STSAuth Auth
}
func (sts *stsCreds) ExpiringKeyForSigning(now time.Time) (*SigningKey, time.Time, error) {
r, err := http.NewRequest(http.MethodPost, fmt.Sprintf("https://sts.%s.amazonaws.com/?%s", sts.Region, (url.Values{
"Version": []string{"2011-06-15"},
"Action": []string{"AssumeRole"},
"RoleSessionName": []string{sts.SessionName},
"RoleArn": []string{sts.RoleARN},
}).Encode()), bytes.NewReader([]byte{}))
if err != nil {
return nil, time.Time{}, err
}
err = (&Service{
Name: "sts",
Region: sts.Region,
}).Sign(sts.STSAuth, r)
if err != nil {
return nil, time.Time{}, err
}
resp, err := http.DefaultClient.Do(r)
if err != nil {
return nil, time.Time{}, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, time.Time{}, errors.New("bad status code")
}
var wrapper struct {
AssumeRoleResult struct {
Credentials struct {
AccessKeyId string
SecretAccessKey string
SessionToken string
Expiration time.Time
}
}
}
err = xml.NewDecoder(resp.Body).Decode(&wrapper)
if err != nil {
return nil, time.Time{}, err
}
// sanity check at least 1 field
if wrapper.AssumeRoleResult.Credentials.SecretAccessKey == "" {
return nil, time.Time{}, errors.New("bad data back")
}
return &SigningKey{
AccessKeyId: wrapper.AssumeRoleResult.Credentials.AccessKeyId,
SecretAccessKey: wrapper.AssumeRoleResult.Credentials.SecretAccessKey,
SessionToken: wrapper.AssumeRoleResult.Credentials.SessionToken,
}, wrapper.AssumeRoleResult.Credentials.Expiration, nil
}