in sdk/auth/credentials/credentials.go [1270:1388]
func (provider *OIDCCredentialsProvider) getCredentials() (sessionCredentials *SessionCredentials, err error) {
method := "POST"
var host string
if provider.stsEndpoint != "" {
host = provider.stsEndpoint
} else if provider.stsRegion != "" {
host = fmt.Sprintf("sts.%s.aliyuncs.com", provider.stsRegion)
} else {
host = "sts.aliyuncs.com"
}
queries := make(map[string]string)
queries["Version"] = "2015-04-01"
queries["Action"] = "AssumeRoleWithOIDC"
queries["Format"] = "JSON"
queries["Timestamp"] = utils.GetTimeInFormatISO8601()
bodyForm := make(map[string]string)
bodyForm["RoleArn"] = provider.roleArn
bodyForm["OIDCProviderArn"] = provider.oidcProviderARN
token, err := ioutil.ReadFile(provider.oidcTokenFilePath)
if err != nil {
return
}
bodyForm["OIDCToken"] = string(token)
if provider.policy != "" {
bodyForm["Policy"] = provider.policy
}
bodyForm["RoleSessionName"] = provider.roleSessionName
bodyForm["DurationSeconds"] = strconv.Itoa(provider.durationSeconds)
// caculate signature
signParams := make(map[string]string)
for key, value := range queries {
signParams[key] = value
}
for key, value := range bodyForm {
signParams[key] = value
}
querystring := utils.GetUrlFormedMap(queries)
// do request
httpUrl := fmt.Sprintf("https://%s/?%s", host, querystring)
body := utils.GetUrlFormedMap(bodyForm)
httpRequest, err := hookNewRequest(http.NewRequest)(method, httpUrl, strings.NewReader(body))
if err != nil {
return
}
// set headers
httpRequest.Header["Accept-Encoding"] = []string{"identity"}
httpRequest.Header["Content-Type"] = []string{"application/x-www-form-urlencoded"}
connectTimeout := 5 * time.Second
readTimeout := 10 * time.Second
if provider.httpOptions != nil && provider.httpOptions.ConnectTimeout > 0 {
connectTimeout = provider.httpOptions.ConnectTimeout
}
if provider.httpOptions != nil && provider.httpOptions.ReadTimeout > 0 {
readTimeout = provider.httpOptions.ReadTimeout
}
transport := http.DefaultTransport.(*http.Transport).Clone()
transport.DialContext = func(ctx context.Context, network, address string) (net.Conn, error) {
return (&net.Dialer{
Timeout: connectTimeout,
DualStack: true,
}).DialContext(ctx, network, address)
}
httpClient := &http.Client{
Timeout: connectTimeout + readTimeout,
Transport: transport,
}
httpResponse, err := hookDo(httpClient.Do)(httpRequest)
if err != nil {
return
}
defer httpResponse.Body.Close()
responseBody, err := ioutil.ReadAll(httpResponse.Body)
if err != nil {
return
}
if httpResponse.StatusCode != http.StatusOK {
message := "get session token failed"
err = errors.NewServerError(httpResponse.StatusCode, string(responseBody), message)
return
}
var data assumeRoleResponse
err = json.Unmarshal(responseBody, &data)
if err != nil {
err = fmt.Errorf("get oidc sts token err, json.Unmarshal fail: %s", err.Error())
return
}
if data.Credentials == nil {
err = fmt.Errorf("get oidc sts token err, fail to get credentials")
return
}
if data.Credentials.AccessKeyId == nil || data.Credentials.AccessKeySecret == nil || data.Credentials.SecurityToken == nil {
err = fmt.Errorf("refresh RoleArn sts token err, fail to get credentials")
return
}
sessionCredentials = &SessionCredentials{
AccessKeyId: *data.Credentials.AccessKeyId,
AccessKeySecret: *data.Credentials.AccessKeySecret,
SecurityToken: *data.Credentials.SecurityToken,
Expiration: *data.Credentials.Expiration,
}
return
}