diff --git a/.changes/nextrelease/configured-signature-version.json b/.changes/nextrelease/configured-signature-version.json new file mode 100644 index 0000000000..dd4761264e --- /dev/null +++ b/.changes/nextrelease/configured-signature-version.json @@ -0,0 +1,7 @@ +[ + { + "type": "bugfix", + "category": "", + "description": "Fixes issue with manually configured signature versions." + } +] \ No newline at end of file diff --git a/src/AwsClient.php b/src/AwsClient.php index 33e270017d..3f2b03699e 100644 --- a/src/AwsClient.php +++ b/src/AwsClient.php @@ -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); @@ -403,7 +403,7 @@ private function addEndpointDiscoveryMiddleware($config, $args) } } - private function addSignatureMiddleware() + private function addSignatureMiddleware(array $args) { $api = $this->getApi(); $provider = $this->signatureProvider; @@ -411,9 +411,17 @@ private function addSignatureMiddleware() $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']; } @@ -421,30 +429,33 @@ private function addSignatureMiddleware() $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( diff --git a/src/ClientResolver.php b/src/ClientResolver.php index fd9427dc26..e0b650fb24 100644 --- a/src/ClientResolver.php +++ b/src/ClientResolver.php @@ -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 { diff --git a/tests/AwsClientTest.php b/tests/AwsClientTest.php index bc354f83ba..a9aabeb843 100644 --- a/tests/AwsClientTest.php +++ b/tests/AwsClientTest.php @@ -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; @@ -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) {