Skip to content

Commit

Permalink
bugfix: configured signature versions (#2914)
Browse files Browse the repository at this point in the history
  • Loading branch information
stobrien89 authored May 3, 2024
1 parent aa08a9f commit 000909f
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 25 deletions.
7 changes: 7 additions & 0 deletions .changes/nextrelease/configured-signature-version.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[
{
"type": "bugfix",
"category": "",
"description": "Fixes issue with manually configured signature versions."
}
]
61 changes: 36 additions & 25 deletions src/AwsClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ public function __construct(array $args)
$this->defaultRequestOptions = $config['http'];
$this->endpointProvider = $config['endpoint_provider'];
$this->serializer = $config['serializer'];
$this->addSignatureMiddleware();
$this->addSignatureMiddleware($args);
$this->addInvocationId();
$this->addEndpointParameterMiddleware($args);
$this->addEndpointDiscoveryMiddleware($config, $args);
Expand Down Expand Up @@ -403,48 +403,59 @@ private function addEndpointDiscoveryMiddleware($config, $args)
}
}

private function addSignatureMiddleware()
private function addSignatureMiddleware(array $args)
{
$api = $this->getApi();
$provider = $this->signatureProvider;
$version = $this->config['signature_version'];
$name = $this->config['signing_name'];
$region = $this->config['signing_region'];

if (isset($args['signature_version'])
|| isset($this->config['configured_signature_version'])
) {
$configuredSignatureVersion = true;
} else {
$configuredSignatureVersion = false;
}

$resolver = static function (
CommandInterface $c
) use ($api, $provider, $name, $region, $version) {
) use ($api, $provider, $name, $region, $version, $configuredSignatureVersion) {
if (!empty($c['@context']['signing_region'])) {
$region = $c['@context']['signing_region'];
}
if (!empty($c['@context']['signing_service'])) {
$name = $c['@context']['signing_service'];
}

$authType = $api->getOperation($c->getName())['authtype'];
switch ($authType){
case 'none':
$version = 'anonymous';
break;
case 'v4-unsigned-body':
$version = 'v4-unsigned-body';
break;
case 'bearer':
$version = 'bearer';
break;
}
if (isset($c['@context']['signature_version'])) {
if ($c['@context']['signature_version'] == 'v4a') {
$version = 'v4a';
if (!$configuredSignatureVersion) {
$authType = $api->getOperation($c->getName())['authtype'];
switch ($authType){
case 'none':
$version = 'anonymous';
break;
case 'v4-unsigned-body':
$version = 'v4-unsigned-body';
break;
case 'bearer':
$version = 'bearer';
break;
}
if (isset($c['@context']['signature_version'])) {
if ($c['@context']['signature_version'] == 'v4a') {
$version = 'v4a';
}
}
if (!empty($endpointAuthSchemes = $c->getAuthSchemes())) {
$version = $endpointAuthSchemes['version'];
$name = isset($endpointAuthSchemes['name']) ?
$endpointAuthSchemes['name'] : $name;
$region = isset($endpointAuthSchemes['region']) ?
$endpointAuthSchemes['region'] : $region;
}
}
if (!empty($endpointAuthSchemes = $c->getAuthSchemes())) {
$version = $endpointAuthSchemes['version'];
$name = isset($endpointAuthSchemes['name']) ?
$endpointAuthSchemes['name'] : $name;
$region = isset($endpointAuthSchemes['region']) ?
$endpointAuthSchemes['region'] : $region;
}

return SignatureProvider::resolve($provider, $version, $name, $region);
};
$this->handlerList->appendSign(
Expand Down
1 change: 1 addition & 0 deletions src/ClientResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,7 @@ public static function _apply_credentials($value, array &$args)
new Credentials('', '')
);
$args['config']['signature_version'] = 'anonymous';
$args['config']['configured_signature_version'] = true;
} elseif ($value instanceof CacheInterface) {
$args['credentials'] = CredentialProvider::defaultProvider($args);
} else {
Expand Down
56 changes: 56 additions & 0 deletions tests/AwsClientTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Aws\Endpoint\UseFipsEndpoint\Configuration as FipsConfiguration;
use Aws\Endpoint\UseDualStackEndpoint\Configuration as DualStackConfiguration;
use Aws\EndpointV2\EndpointProviderV2;
use Aws\Middleware;
use Aws\ResultPaginator;
use Aws\S3\Exception\S3Exception;
use Aws\Ses\SesClient;
Expand Down Expand Up @@ -670,6 +671,61 @@ public function configuredEndpointUrlProvider()
];
}

public function testAppliesConfiguredSignatureVersionViaFalseCredentials()
{
$client = new S3Client([
'region' => 'us-west-2',
'handler' => new MockHandler([new Result([])]),
'credentials' => false
]);

$this->assertTrue($client->getConfig('configured_signature_version'));

$list = $client->getHandlerList();
$list->appendSign(Middleware::tap(function($cmd, $req) {
foreach (['Authorization', 'X-Amz-Date'] as $signatureHeader) {
$this->assertFalse($req->hasHeader($signatureHeader));
}
}));

$client->putObject([
'Bucket' => 'foo',
'Key' => 'bar',
'Body' => 'test'
]);
}

public function testAppliesConfiguredSignatureVersionViaClientConfig() {
$client = $this->createClient(
[
'metadata' => [
'signatureVersion' => 'v4',
],
'operations' => [
'Foo' => [
'http' => ['method' => 'POST'],
'authtype' => 'none',
],
],
],
[
'handler' => function (
CommandInterface $command,
RequestInterface $request
) {
foreach (['Authorization', 'X-Amz-Date'] as $signatureHeader) {
$this->assertTrue($request->hasHeader($signatureHeader));
}

return new Result;
},
'signature_version' => 'v4'
]
);

$client->foo();
}

private function createHttpsEndpointClient(array $service = [], array $config = [])
{
$apiProvider = function () use ($service) {
Expand Down

0 comments on commit 000909f

Please sign in to comment.