in src/providers/ram_role_arn.ts [175:275]
private async getCredentialsInternal(): Promise<Session> {
const credentials = await this.credentialsProvider.getCredentials();
const method = 'POST';
const builder = Request.builder().withMethod(method).withProtocol('https').withHost(this.stsEndpoint).withReadTimeout(this.readTimeout || 10000).withConnectTimeout(this.connectTimeout || 5000);
const queries = Object.create(null);
queries['Version'] = '2015-04-01';
queries['Action'] = 'AssumeRole';
queries['Format'] = 'JSON';
queries['Timestamp'] = utils.timestamp();
queries['SignatureMethod'] = 'HMAC-SHA1';
queries['SignatureVersion'] = '1.0';
queries['SignatureNonce'] = kitx.makeNonce();
queries['AccessKeyId'] = credentials.accessKeyId;
if (credentials.securityToken) {
queries['SecurityToken'] = credentials.securityToken;
}
const bodyForm = Object.create(null);
bodyForm['RoleArn'] = this.roleArn;
if (this.policy) {
bodyForm['Policy'] = this.policy;
}
if (this.externalId) {
bodyForm['ExternalId'] = this.externalId;
}
bodyForm['RoleSessionName'] = this.roleSessionName
bodyForm['DurationSeconds'] = `${this.durationSeconds}`;
builder.withBodyForm(bodyForm);
// caculate signature
const signParams = Object.create(null);
for (const [key, value] of Object.entries(queries)) {
signParams[key] = value
}
for (const [key, value] of Object.entries(bodyForm)) {
signParams[key] = value
}
const keys = Object.keys(signParams).sort();
const stringToSign = `${method}&${encode('/')}&${encode(keys.map((key) => {
return `${encode(key)}=${encode(signParams[key])}`;
}).join('&'))}`;
log('stringToSign[Client]:');
log(stringToSign);
const secret = credentials.accessKeySecret + '&';
const signature = kitx.sha1(stringToSign, secret, 'base64') as string;
queries['Signature'] = signature;
builder.withQueries(queries);
const headers = Object.create(null);
// set headers
headers['Content-Type'] = 'application/x-www-form-urlencoded';
headers['x-acs-credentials-provider'] = credentials.providerName
builder.withHeaders(headers);
// if (this.httpOptions) {
// req.connectTimeout = this.httpOptions.connectTimeout;
// req.readTimeout = this.httpOptions.readTimeout;
// req.proxy = this.httpOptions.proxy;
// }
const request = builder.build();
const response = await this.doRequest(request);
if (response.statusCode != 200) {
if (response.headers['content-type'] && response.headers['content-type'].startsWith('application/json')) {
const body = JSON.parse(response.body.toString('utf8'));
const serverStringToSign = (body.Message as string).slice('Specified signature is not matched with our calculation. server string to sign is:'.length);
log('stringToSign[Server]:')
log(stringToSign)
if (body.Code === 'SignatureDoesNotMatch' && serverStringToSign === stringToSign) {
throw new Error(`the access key secret is invalid`);
}
}
throw new Error(`refresh session token failed: ${response.body.toString('utf8')}`)
}
let data;
try {
data = JSON.parse(response.body.toString('utf8'));
} catch (ex) {
throw new Error(`refresh RoleArn sts token err, unmarshal fail: ${response.body.toString('utf8')}`);
}
if (!data || !data.Credentials) {
throw new Error(`refresh RoleArn sts token err, fail to get credentials`);
}
if (!data.Credentials.AccessKeyId || !data.Credentials.AccessKeySecret || !data.Credentials.SecurityToken) {
throw new Error('refresh RoleArn sts token err, fail to get credentials')
}
const { AccessKeyId, AccessKeySecret, SecurityToken, Expiration } = data.Credentials;
return new Session(AccessKeyId, AccessKeySecret, SecurityToken, Expiration);
}