-
Notifications
You must be signed in to change notification settings - Fork 192
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Allow Impersonated SA Credentials to make requests authenticate…
…d with an IdToken feat: Allow Impersonated SA Credentials to make requests authenticated with an IdToken chore: Removed uncommented code
- Loading branch information
Showing
7 changed files
with
187 additions
and
24 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ | |
use Google\Auth\ApplicationDefaultCredentials; | ||
use Google\Auth\Credentials\ExternalAccountCredentials; | ||
use Google\Auth\Credentials\GCECredentials; | ||
use Google\Auth\Credentials\ImpersonatedServiceAccountCredentials; | ||
use Google\Auth\Credentials\ServiceAccountCredentials; | ||
use Google\Auth\CredentialsLoader; | ||
use Google\Auth\CredentialSource; | ||
|
@@ -155,6 +156,13 @@ public function testGceCredentials() | |
$this->assertStringContainsString('a+user+scope', $tokenUri); | ||
} | ||
|
||
public function testGetIdTokenCredentialsCanFindImpersonatedServiceAccountCredentials() | ||
{ | ||
putenv('GOOGLE_APPLICATION_CREDENTIALS=' . __DIR__ . '/fixtures3/impersonated_service_account_credentials.json'); | ||
$creds = ApplicationDefaultCredentials::getIdTokenCredentials('[email protected]'); | ||
$this->assertInstanceOf(ImpersonatedServiceAccountCredentials::class, $creds); | ||
} | ||
|
||
public function testImpersonatedServiceAccountCredentials() | ||
{ | ||
putenv('HOME=' . __DIR__ . '/fixtures5'); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,24 +19,25 @@ | |
namespace Google\Auth\Tests\Credentials; | ||
|
||
use Google\Auth\Credentials\ImpersonatedServiceAccountCredentials; | ||
use Google\Auth\Credentials\UserRefreshCredentials; | ||
use Google\Auth\Middleware\AuthTokenMiddleware; | ||
use GuzzleHttp\Psr7\Request; | ||
use GuzzleHttp\Psr7\Response; | ||
use LogicException; | ||
use PHPUnit\Framework\TestCase; | ||
use Prophecy\PhpUnit\ProphecyTrait; | ||
use Psr\Http\Message\RequestInterface; | ||
use Psr\Http\Message\ResponseInterface; | ||
use Psr\Http\Message\StreamInterface; | ||
|
||
class ImpersonatedServiceAccountCredentialsTest extends TestCase | ||
{ | ||
use ProphecyTrait; | ||
|
||
// Creates a standard JSON auth object for testing. | ||
private function createISACTestJson() | ||
{ | ||
return [ | ||
'type' => 'impersonated_service_account', | ||
'service_account_impersonation_url' => 'https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/[email protected]:generateAccessToken', | ||
'source_credentials' => [ | ||
'client_id' => 'client123', | ||
'client_secret' => 'clientSecret123', | ||
'refresh_token' => 'refreshToken123', | ||
'type' => 'authorized_user', | ||
] | ||
]; | ||
return json_decode(file_get_contents(__DIR__ . '/../fixtures3/impersonated_service_account_credentials.json'), true); | ||
} | ||
|
||
public function testGetServiceAccountNameEmail() | ||
|
@@ -69,4 +70,76 @@ public function testErrorCredentials() | |
$this->expectException(LogicException::class); | ||
new ImpersonatedServiceAccountCredentials($scope, $testJson['source_credentials']); | ||
} | ||
|
||
public function testGetIdToken() | ||
{ | ||
$testJson = $this->createISACTestJson(); | ||
$targetAudience = '[email protected]'; | ||
$creds = new ImpersonatedServiceAccountCredentials(null, $testJson, null, $targetAudience); | ||
|
||
$requestCount = 0; | ||
// getting an id token will take two requests | ||
$httpHandler = function (RequestInterface $request) use (&$requestCount, $creds) { | ||
$impersonatedServiceAccount = $creds->getClientName(); | ||
|
||
$responseBody = ''; | ||
switch (++$requestCount) { | ||
case 1: // the call to swap the refresh token for an access token | ||
$this->assertEquals(UserRefreshCredentials::TOKEN_CREDENTIAL_URI, (string) $request->getUri()); | ||
$responseBody = '{"access_token":"this is an access token"}'; | ||
break; | ||
|
||
case 2: // the call to swap the access token for an id token | ||
$this->assertEquals("https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/{$impersonatedServiceAccount}:generateIdToken", (string) $request->getUri()); | ||
$authHeader = $request->getHeader('authorization'); | ||
$this->assertCount(1, $authHeader); | ||
$this->assertEquals('Bearer this is an access token', $authHeader[0]); | ||
$responseBody = '{"token": "this is the id token"}'; | ||
break; | ||
} | ||
|
||
$body = $this->prophesize(StreamInterface::class); | ||
$body->__toString()->willReturn($responseBody); | ||
|
||
$response = $this->prophesize(ResponseInterface::class); | ||
$response->getBody()->willReturn($body->reveal()); | ||
$response->hasHeader('Content-Type')->willReturn(true); | ||
$response->getHeaderLine('Content-Type')->willReturn('application/json'); | ||
|
||
if ($requestCount === 2) { | ||
$response->hasHeader('Content-Type')->willReturn(false); | ||
} | ||
|
||
return $response->reveal(); | ||
}; | ||
|
||
$creds->fetchAuthToken($httpHandler); | ||
// any checks on the result are futile as they have been coded above | ||
} | ||
public function testCanBeUsedInAuthTokenMiddlewareWhenAnAudienceIsGiven() | ||
{ | ||
$targetAudience = '[email protected]'; | ||
$jsonKey = $this->createISACTestJson(); | ||
$credentials = new ImpersonatedServiceAccountCredentials(null, $jsonKey, null, $targetAudience); | ||
|
||
// this handler is for the middleware constructor, which will pass it to the ISAC to fetch tokens | ||
$httpHandler = getHandler([ | ||
new Response(200, ['Content-Type' => 'application/json'], '{"access_token":"this.is.an.access.token"}'), | ||
new Response(200, ['Content-Type' => 'application/json'], '{"token":"this.is.an.id.token"}'), | ||
]); | ||
$middleware = new AuthTokenMiddleware($credentials, $httpHandler); | ||
|
||
// this handler is the actual handler that makes the authenticated request | ||
$httpHandler = function (RequestInterface $request) use (&$requestCount) { | ||
$this->assertTrue($request->hasHeader('authorization')); | ||
$authHeader = $request->getHeader('authorization'); | ||
$this->assertCount(1, $authHeader); | ||
$this->assertEquals('Bearer this.is.an.id.token', $authHeader[0]); | ||
}; | ||
|
||
$middleware($httpHandler)( | ||
new Request('GET', 'https://www.google.com'), | ||
['auth' => 'google_auth'] | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
10 changes: 10 additions & 0 deletions
10
tests/fixtures3/impersonated_service_account_credentials.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"type": "impersonated_service_account", | ||
"service_account_impersonation_url": "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/[email protected]:generateAccessToken", | ||
"source_credentials": { | ||
"client_id": "client123", | ||
"client_secret": "clientSecret123", | ||
"refresh_token": "refreshToken123", | ||
"type": "authorized_user" | ||
} | ||
} |