gpt4 book ai didi

php - PUT请求的Amazon ElasticSearch服务签名不匹配-Amazon SDK PHP V2

转载 作者:行者123 更新时间:2023-12-03 00:07:30 24 4
gpt4 key购买 nike

我正在使用Amazon ElasticSearch Service,当我尝试创建SignatureV4 Request时,它对于搜索操作(GET Requests)工作正常。但是,当我尝试执行诸如创建索引(使用PUT请求)之类的某些操作时,它将穿过“签名不匹配”错误。

我正在使用Amazon SDK版本2 SignatureV4库对请求进行签名。还创建了一个定制的Elasticsearch处理程序,以将 token 添加到请求中。

是否有人对Amazon SDK php V2中的SignatureV4库有此类问题。

{"message":"The request signature we calculated does not match the signature you provided. Check your AWS Secret Access Key and signing method. Consult the  service documentation for details.\n\nThe Canonical String for this request should have been\n'PUT\n/test_index_2\n\nhost:search-test-gps2gj4zx654muo6a5m3vxm3cy.eu-west-1.es.amazonaws.com\nx-amz-date:XXXXXXXXXXXX\n\nhost;x-amz-date\n271d5ef919251148dc0b5b3f3968c3debc911a41b60ef4e92c55b98057d6cdd4'\n\nThe String-to-Sign should have been\n'AWS4-HMAC-SHA256\XXXXXXXXXXXX\n20170511/eu-west-1/es/aws4_request\n0bd34812e0727fba7c54068b0ae1114db235cfc2f97059b88be43e8b264e1d57'\n"}

最佳答案

仅对于仍在使用Amazon SDK PHP版本2的用户,此调整是必需的。在版本3中,默认情况下支持。

对于已签名的请求,我通过添加用于签名请求的中间件来更新了当前的elsticsearch客户端处理程序。

$elasticConfig = Configure::read('ElasticSearch');
$middleware = new AwsSignatureMiddleware();
$defaultHandler = \Elasticsearch\ClientBuilder::defaultHandler();
$awsHandler = $middleware($defaultHandler);

$clientBuilder = \Elasticsearch\ClientBuilder::create();
$clientBuilder->setHandler($awsHandler)
->setHosts([$elasticConfig['host'].':'.$elasticConfig['port']]);
$client = $clientBuilder->build();

我为此使用了以下库
use Aws\Common\Credentials\CredentialsInterface;
use Aws\Common\Signature\SignatureInterface;
use Guzzle\Http\Message\Request;

class AwsSignatureMiddleware
{
/**
* @var \Aws\Credentials\CredentialsInterface
*/
protected $credentials;

/**
* @var \Aws\Signature\SignatureInterface
*/
protected $signature;

/**
* @param CredentialsInterface $credentials
* @param SignatureInterface $signature
*/
public function __construct()
{
$amazonConf = Configure::read('AmazonSDK');
$this->credentials = new \Aws\Common\Credentials\Credentials($amazonConf['key'], $amazonConf['secret']);
$this->signature = new \Aws\Common\Signature\SignatureV4('es', 'eu-west-1');
}

/**
* @param $handler
* @return callable
*/
public function __invoke($handler)
{
return function ($request) use ($handler) {
$headers = $request['headers'];
if ($headers['host']) {
if (is_array($headers['host'])) {
$headers['host'] = array_map([$this, 'removePort'], $headers['host']);
} else {
$headers['host'] = $this->removePort($headers['host']);
}
}
if (!empty($request['body'])) {
$headers['x-amz-content-sha256'] = hash('sha256', $request['body']);
}

$psrRequest = new Request($request['http_method'], $request['uri'], $headers);
$this->signature->signRequest($psrRequest, $this->credentials);
$headerObj = $psrRequest->getHeaders();
$allHeaders = $headerObj->getAll();

$signedHeaders = array();
foreach ($allHeaders as $header => $allHeader) {
$signedHeaders[$header] = $allHeader->toArray();
}
$request['headers'] = array_merge($signedHeaders, $request['headers']);
return $handler($request);
};
}

protected function removePort($host)
{
return parse_url($host)['host'];
}
}

我为此调整的确切行是
if (!empty($request['body'])) {
$headers['x-amz-content-sha256'] = hash('sha256', $request['body']);
}

对于PUT和POST请求,有效负载哈希是错误的,因为在生成有效负载时我没有考虑请求正文。

希望此代码对使用Amazon SDK PHP版本2并在Amazon云中使用基于IAM的Elasticsearch Hosted服务的身份验证的用户有所帮助。

关于php - PUT请求的Amazon ElasticSearch服务签名不匹配-Amazon SDK PHP V2,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43913884/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com