Skip to content

Commit cbedf9a

Browse files
committed
implemented auth with metadata url
1 parent 48d3bde commit cbedf9a

File tree

1 file changed

+79
-3
lines changed

1 file changed

+79
-3
lines changed

src/Iam.php

Lines changed: 79 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class Iam implements IamTokenContract
1616

1717
const IAM_TOKEN_API_URL = 'https://iam.api.cloud.yandex.net/iam/v1/tokens';
1818

19+
const METADATA_URL = 'http://169.254.169.254/computeMetadata/v1/instance/service-accounts/default/token';
20+
1921
const DEFAULT_TOKEN_EXPIRES_AT = 2; // hours
2022

2123
/**
@@ -86,7 +88,11 @@ public function newToken()
8688
{
8789
$this->logger()->info('YDB: Obtaining new IAM token...');
8890

89-
if ($this->config('private_key'))
91+
if ($this->config('use_metadata'))
92+
{
93+
return $this->requestTokenFromMetadata();
94+
}
95+
else if ($this->config('private_key'))
9096
{
9197
$token = $this->getJwtToken();
9298

@@ -174,7 +180,11 @@ protected function initConfig()
174180
$this->config['temp_dir'] = sys_get_temp_dir();
175181
}
176182

177-
if (!empty($this->config['service_file']))
183+
if (!empty($this->config['use_metadata']))
184+
{
185+
$this->logger()->info('YDB: Authentication method: Metadata URL');
186+
}
187+
else if (!empty($this->config['service_file']))
178188
{
179189
if (is_file($this->config['service_file']))
180190
{
@@ -250,6 +260,67 @@ protected function getJwtToken()
250260
return $token;
251261
}
252262

263+
/**
264+
* @return string|null
265+
* @throws Exception
266+
*/
267+
protected function requestTokenFromMetadata()
268+
{
269+
$curl = curl_init(static::METADATA_URL);
270+
271+
curl_setopt_array($curl, [
272+
CURLOPT_RETURNTRANSFER => 1,
273+
CURLOPT_SSL_VERIFYPEER => 0,
274+
CURLOPT_SSL_VERIFYHOST => 0,
275+
CURLOPT_HEADER => 0,
276+
CURLOPT_HTTPHEADER => [
277+
'Accept: application/json',
278+
'Metadata-Flavor:Google',
279+
],
280+
]);
281+
282+
$result = curl_exec($curl);
283+
284+
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
285+
286+
if ($status === 200)
287+
{
288+
$rawToken = json_decode($result);
289+
290+
if (isset($rawToken->access_token))
291+
{
292+
$token = (object)[
293+
'iamToken' => $rawToken->access_token,
294+
];
295+
if (isset($rawToken->expires_in))
296+
{
297+
$token->expiresAt = time() + $rawToken->expires_in;
298+
}
299+
$this->logger()->info('YDB: Obtained new IAM token from Metadata [...' . substr($token->iamToken, -6) . '].');
300+
$this->saveToken($token);
301+
return $token->iamToken;
302+
}
303+
else
304+
{
305+
$this->logger()->error('YDB: Failed to obtain new IAM token from Metadata', [
306+
'status' => $status,
307+
'result' => $result,
308+
]);
309+
throw new Exception('Failed to obtain new iamToken from Metadata: no token was received.');
310+
}
311+
}
312+
else
313+
{
314+
$this->logger()->error('YDB: Failed to obtain new IAM token from Metadata', [
315+
'status' => $status,
316+
'result' => $result,
317+
]);
318+
throw new Exception('Failed to obtain new iamToken from Metadata: response status is ' . $status);
319+
}
320+
321+
322+
}
323+
253324
/**
254325
* @var string
255326
*/
@@ -325,7 +396,7 @@ protected function saveToken($token)
325396
$tokenFile = $this->getTokenTempFile();
326397

327398
$this->iam_token = $token->iamToken;
328-
$this->expires_at = $this->convertExpiresAt($token->expiresAt);
399+
$this->expires_at = $this->convertExpiresAt($token->expiresAt ?? '');
329400

330401
file_put_contents($tokenFile, json_encode([
331402
'iamToken' => $this->iam_token,
@@ -339,6 +410,11 @@ protected function saveToken($token)
339410
*/
340411
protected function convertExpiresAt($expiresAt)
341412
{
413+
if (is_int($expiresAt))
414+
{
415+
return $expiresAt;
416+
}
417+
342418
$time = time() + 60 * 60 * static::DEFAULT_TOKEN_EXPIRES_AT;
343419
if (preg_match('/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.\d+)?(.*)$/', $expiresAt, $matches))
344420
{

0 commit comments

Comments
 (0)