private async getCredentialsInternal()

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);
  }