Skip to content

Commit

Permalink
add impersonated service account support in external account credentials
Browse files Browse the repository at this point in the history
  • Loading branch information
bshaffer committed Oct 5, 2023
1 parent 5be4c5e commit e076b11
Showing 1 changed file with 59 additions and 5 deletions.
64 changes: 59 additions & 5 deletions src/Credentials/ExternalAccountCredentials.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,12 @@
use Google\Auth\CredentialSource\UrlSource;
use Google\Auth\ExternalAccountCredentialSourceInterface;
use Google\Auth\FetchAuthTokenInterface;
use Google\Auth\HttpHandler\HttpClientCache;
use Google\Auth\HttpHandler\HttpHandlerFactory;
use Google\Auth\OAuth2;
use Google\Auth\UpdateMetadataInterface;
use Google\Auth\UpdateMetadataTrait;
use GuzzleHttp\Psr7\Request;
use InvalidArgumentException;

class ExternalAccountCredentials implements FetchAuthTokenInterface, UpdateMetadataInterface
Expand All @@ -34,6 +37,7 @@ class ExternalAccountCredentials implements FetchAuthTokenInterface, UpdateMetad
private const EXTERNAL_ACCOUNT_TYPE = 'external_account';

private OAuth2 $auth;
private ?string $serviceAccountImpersonationUrl;

/**
* @param string|string[] $scope The scope of the access request, expressed either as an array
Expand Down Expand Up @@ -79,6 +83,10 @@ public function __construct(
);
}

if (array_key_exists('service_account_impersonation_url', $jsonKey)) {
$this->serviceAccountImpersonationUrl = $jsonKey['service_account_impersonation_url'];
}

$this->auth = new OAuth2([
'tokenCredentialUri' => $jsonKey['token_url'],
'audience' => $jsonKey['audience'],
Expand Down Expand Up @@ -142,6 +150,46 @@ private static function buildCredentialSource(array $jsonKey): ExternalAccountCr

throw new InvalidArgumentException('Unable to determine credential source from json key.');
}
/**
* @param string $stsToken
* @param callable $httpHandler
*
* @return array<mixed> {
* A set of auth related metadata, containing the following
*
* @type string $access_token
* @type int $expires_at
* }
*/
private function getImpersonatedAccessToken(string $stsToken, callable $httpHandler = null): array
{
if (is_null($this->serviceAccountImpersonationUrl)) {
throw new InvalidArgumentException(
'service_account_impersonation_url must be set in JSON credentials.'
);
}
$request = new Request(
'POST',
$this->serviceAccountImpersonationUrl,
[
'Content-Type' => 'application/json',
'Authorization' => 'Bearer ' . $stsToken,
],
json_encode([

Check failure on line 178 in src/Credentials/ExternalAccountCredentials.php

View workflow job for this annotation

GitHub Actions / PHPStan Static Analysis

Parameter #4 $body of class GuzzleHttp\Psr7\Request constructor expects Psr\Http\Message\StreamInterface|resource|string|null, string|false given.
'lifetime' => sprintf('%ss', OAuth2::DEFAULT_EXPIRY_SECONDS),
'scope' => $this->auth->getScope(),
]),
);
if (is_null($httpHandler)) {
$httpHandler = HttpHandlerFactory::build(HttpClientCache::getHttpClient());
}
$response = $httpHandler($request);
$body = json_decode((string) $response->getBody(), true);
return [
'access_token' => $body['accessToken'],
'expires_at' => strtotime($body['expireTime']),
];
}

/**
* @param callable $httpHandler
Expand All @@ -150,15 +198,21 @@ private static function buildCredentialSource(array $jsonKey): ExternalAccountCr
* A set of auth related metadata, containing the following
*
* @type string $access_token
* @type int $expires_in
* @type string $scope
* @type string $token_type
* @type string $id_token
* @type int $expires_at (impersonated service accounts only)
* @type int $expires_in (identity pool only)
* @type string $issued_token_type (identity pool only)
* @type string $token_type (identity pool only)
* }
*/
public function fetchAuthToken(callable $httpHandler = null)
{
return $this->auth->fetchAuthToken($httpHandler);
$stsToken = $this->auth->fetchAuthToken($httpHandler);

if ($this->serviceAccountImpersonationUrl) {
return $this->getImpersonatedAccessToken($stsToken['access_token'], $httpHandler);
}

return $stsToken;
}

public function getCacheKey()
Expand Down

0 comments on commit e076b11

Please sign in to comment.