PluginProbe ʕ •ᴥ•ʔ
Transferito: WP Migration / trunk
Transferito: WP Migration vtrunk
trunk 11.4.0 12.0.0 13.1.0 14.0.0 14.0.11 14.0.7 14.1.0 14.1.1 14.1.2 14.1.3 14.1.4
transferito / vendor / aws / aws-sdk-php / src / Credentials / AssumeRoleWithWebIdentityCredentialProvider.php
transferito / vendor / aws / aws-sdk-php / src / Credentials Last commit date
AssumeRoleCredentialProvider.php 11 months ago AssumeRoleWithWebIdentityCredentialProvider.php 11 months ago CredentialProvider.php 11 months ago Credentials.php 11 months ago CredentialsInterface.php 11 months ago EcsCredentialProvider.php 11 months ago InstanceProfileProvider.php 11 months ago
AssumeRoleWithWebIdentityCredentialProvider.php
167 lines
1 <?php
2 namespace Aws\Credentials;
3
4 use Aws\Exception\AwsException;
5 use Aws\Exception\CredentialsException;
6 use Aws\Result;
7 use Aws\Sts\StsClient;
8 use GuzzleHttp\Promise;
9
10 /**
11 * Credential provider that provides credentials via assuming a role with a web identity
12 * More Information, see: https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sts-2011-06-15.html#assumerolewithwebidentity
13 */
14 class AssumeRoleWithWebIdentityCredentialProvider
15 {
16 const ERROR_MSG = "Missing required 'AssumeRoleWithWebIdentityCredentialProvider' configuration option: ";
17 const ENV_RETRIES = 'AWS_METADATA_SERVICE_NUM_ATTEMPTS';
18
19 /** @var string */
20 private $tokenFile;
21
22 /** @var string */
23 private $arn;
24
25 /** @var string */
26 private $session;
27
28 /** @var StsClient */
29 private $client;
30
31 /** @var integer */
32 private $retries;
33
34 /** @var integer */
35 private $authenticationAttempts;
36
37 /** @var integer */
38 private $tokenFileReadAttempts;
39
40 /**
41 * The constructor attempts to load config from environment variables.
42 * If not set, the following config options are used:
43 * - WebIdentityTokenFile: full path of token filename
44 * - RoleArn: arn of role to be assumed
45 * - SessionName: (optional) set by SDK if not provided
46 *
47 * @param array $config Configuration options
48 * @throws \InvalidArgumentException
49 */
50 public function __construct(array $config = [])
51 {
52 if (!isset($config['RoleArn'])) {
53 throw new \InvalidArgumentException(self::ERROR_MSG . "'RoleArn'.");
54 }
55 $this->arn = $config['RoleArn'];
56
57 if (!isset($config['WebIdentityTokenFile'])) {
58 throw new \InvalidArgumentException(self::ERROR_MSG . "'WebIdentityTokenFile'.");
59 }
60 $this->tokenFile = $config['WebIdentityTokenFile'];
61
62 if (!preg_match("/^\w\:|^\/|^\\\/", $this->tokenFile)) {
63 throw new \InvalidArgumentException("'WebIdentityTokenFile' must be an absolute path.");
64 }
65
66 $this->retries = (int) getenv(self::ENV_RETRIES) ?: (isset($config['retries']) ? $config['retries'] : 3);
67 $this->authenticationAttempts = 0;
68 $this->tokenFileReadAttempts = 0;
69
70 $this->session = isset($config['SessionName'])
71 ? $config['SessionName']
72 : 'aws-sdk-php-' . round(microtime(true) * 1000);
73
74 $region = isset($config['region'])
75 ? $config['region']
76 : 'us-east-1';
77
78 if (isset($config['client'])) {
79 $this->client = $config['client'];
80 } else {
81 $this->client = new StsClient([
82 'credentials' => false,
83 'region' => $region,
84 'version' => 'latest'
85 ]);
86 }
87 }
88
89 /**
90 * Loads assume role with web identity credentials.
91 *
92 * @return Promise\PromiseInterface
93 */
94 public function __invoke()
95 {
96 return Promise\Coroutine::of(function () {
97 $client = $this->client;
98 $result = null;
99 while ($result == null) {
100 try {
101 $token = @file_get_contents($this->tokenFile);
102 if (false === $token) {
103 clearstatcache(true, dirname($this->tokenFile) . "/" . readlink($this->tokenFile));
104 clearstatcache(true, dirname($this->tokenFile) . "/" . dirname(readlink($this->tokenFile)));
105 clearstatcache(true, $this->tokenFile);
106 if (!@is_readable($this->tokenFile)) {
107 throw new CredentialsException(
108 "Unreadable tokenfile at location {$this->tokenFile}"
109 );
110 }
111
112 $token = @file_get_contents($this->tokenFile);
113 }
114 if (empty($token)) {
115 if ($this->tokenFileReadAttempts < $this->retries) {
116 sleep((int) pow(1.2, $this->tokenFileReadAttempts));
117 $this->tokenFileReadAttempts++;
118 continue;
119 }
120 throw new CredentialsException("InvalidIdentityToken from file: {$this->tokenFile}");
121 }
122 } catch (\Exception $exception) {
123 throw new CredentialsException(
124 "Error reading WebIdentityTokenFile from " . $this->tokenFile,
125 0,
126 $exception
127 );
128 }
129
130 $assumeParams = [
131 'RoleArn' => $this->arn,
132 'RoleSessionName' => $this->session,
133 'WebIdentityToken' => $token
134 ];
135
136 try {
137 $result = $client->assumeRoleWithWebIdentity($assumeParams);
138 } catch (AwsException $e) {
139 if ($e->getAwsErrorCode() == 'InvalidIdentityToken') {
140 if ($this->authenticationAttempts < $this->retries) {
141 sleep((int) pow(1.2, $this->authenticationAttempts));
142 } else {
143 throw new CredentialsException(
144 "InvalidIdentityToken, retries exhausted"
145 );
146 }
147 } else {
148 throw new CredentialsException(
149 "Error assuming role from web identity credentials",
150 0,
151 $e
152 );
153 }
154 } catch (\Exception $e) {
155 throw new CredentialsException(
156 "Error retrieving web identity credentials: " . $e->getMessage()
157 . " (" . $e->getCode() . ")"
158 );
159 }
160 $this->authenticationAttempts++;
161 }
162
163 yield $this->client->createCredentials($result);
164 });
165 }
166 }
167