我无法使用签名请求在AWS托管的Elasticsearch集群中索引文档。
基础设施设置
Elasticsearch版本:7.4
准入政策:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "*"
},
"Action": "es:*",
"Resource": "arn:aws:es:<RESOURCE>/*"
}
]
}代码
下面的代码使用7.6版加载客户端库。我也降低了他们的等级,以匹配集群版本,但没有效果。
build.gradle
// ...
implementation("org.springframework.data:spring-data-elasticsearch")
implementation("org.elasticsearch:elasticsearch")
implementation("org.elasticsearch.client:elasticsearch-rest-high-level-client")
// ...客户端配置定义。环境变量(如AWS_ACCESS_KEY_ID、AWS_SECRET_ACCESS_KEY和AWS_PROFILE )已被填充。
@Configuration
public class ElasticsearchClientConfig extends AbstractElasticsearchConfiguration {
@Value("${elasticsearch.host}")
private String elasticsearchHost;
@Value("${elasticsearch.port}")
private int elasticsearchPort;
@Override
@Bean
public RestHighLevelClient elasticsearchClient() {
var SERVICE_NAME = "es";
var REGION = "us-east-1";
var defaultCP = new DefaultAWSCredentialsProviderChain();
AWS4Signer signer = new AWS4Signer();
signer.setServiceName(SERVICE_NAME);
signer.setRegionName(REGION);
HttpRequestInterceptor interceptor = new AWSRequestSigningApacheInterceptor
(SERVICE_NAME, signer, defaultCP);
RestClientBuilder restClientBuilder = RestClient
.builder(HttpHost.create(elasticsearchHost))
.setHttpClientConfigCallback(hacb -> hacb.addInterceptorLast(interceptor));
return new RestHighLevelClient(restClientBuilder);
}
}AWSRequestSigningApacheInterceptor是从这里中提取的。
到目前一切尚好。当应用程序加载时,它正在访问集群,并设法正确地创建相关索引。
问题
问题是在从Spring数据存储库执行save()操作时。有两个向ES提出的请求。
@Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Cannot save 'null' entity.");
operations.save(entity, getIndexCoordinates());
operations.indexOps(entity.getClass()).refresh();
return entity;
}看看日志,第一个就成功了。以下错误结束第二次调用
org.elasticsearch.client.ResponseException: method [POST], host [HOST], URI [/asset/_refresh?ignore_throttled=false&ignore_unavailable=false&expand_wildcards=open&allow_no_indices=true], status line [HTTP/1.1 403 Forbidden]
{"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."}查看这两个操作的更详细日志。
呼叫保存(以200状态代码结束):
com.amazonaws.auth.AWS4Signer : AWS4 Canonical Request: '"PUT
/asset/_doc/2
timeout=1m
content-length:128
content-type:application/json
host:<HOST>
user-agent:Apache-HttpAsyncClient/4.1.4 (Java/11.0.2)
x-amz-date:20200715T110349Z
content-length;content-type;host;user-agent;x-amz-date
55c1faf282ca0da145667bf7632f667349dbe30ed1edc64439cec2e8d463e176"
2020-07-15 13:03:49.240 DEBUG 3942 --- [nio-8080-exec-1] com.amazonaws.auth.AWS4Signer : AWS4 String to Sign: '"AWS4-HMAC-SHA256
20200715T110349Z
20200715/us-east-1/es/aws4_request
76b6547ad98145ef7ad514baac4ce67fa885bd56073e9855757ade19e28f6fec"呼叫刷新(以403状态代码结尾):
com.amazonaws.auth.AWS4Signer : AWS4 Canonical Request: '"POST
/asset/_refresh
host:<HOST>
user-agent:Apache-HttpAsyncClient/4.1.4 (Java/11.0.2)
x-amz-date:20200715T110349Z
host;user-agent;x-amz-date
bbe4763d6a0252c6e955bcc4884e15035479910b02395548dbb16bcbad1ddf95"
2020-07-15 13:03:49.446 DEBUG 3942 --- [nio-8080-exec-1] com.amazonaws.auth.AWS4Signer : AWS4 String to Sign: '"AWS4-HMAC-SHA256
20200715T110349Z
20200715/us-east-1/es/aws4_request
189b39cf0475734e29c7f9cd5fd845fc95f73c95151a3b6f6d430b95f6bee47e"当直接使用低级客户端索引文档时,一切都很好。我怀疑对于随后的API调用,签名计算行为不正确。
发布于 2022-07-27 08:31:15
我也遇到了同样的问题,在我的例子中,我使用的是AWSRequestSigningApacheInterceptor,而且我使用的是旧版本。升级到最新版本后,它就修好了。
https://stackoverflow.com/questions/62913724
复制相似问题