我在 AWS 上使用 ES 服务。我在学习如何使用它方面取得了很大进步,尤其是在使用 ES HighLevelRestClient 时。所以现在我想保护 ES 服务器,添加用户身份验证安全性。 Amazon 提供“访问 key ”和“ secret key ”值供使用,类似于“用户/密码”凭证。不幸的是,他们还提供了自己的 AWSCredentials 和 AWS4Signer 类来创建凭证和签署请求!
他们的代码示例非常简单,并且可以很好地与 Elastic Co 的 Java“低级”RestClient 配合使用。这是一个类似于亚马逊推荐的片段 https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-indexing-programmatic.html :
credentialsProvider = new AWSStaticCredentialsProvider (new BasicAWSCredentials ("access key", "secret key")); // while debugging
HttpRequestInterceptor interceptor =
new AWSRequestSigningApacheInterceptor (serviceName, signer, credentialsProvider);
RestClient lowLevelClient = RestClient.builder (HttpHost.create (esURL))
.setHttpClientConfigCallback (hacb -> hacb.addInterceptorLast (interceptor)).build ();
好消息是,这很好用!不幸的是,对 ES 高级 Rest 客户端签名版本的明显扩展(如 Add authentication in elasticsearch high level client for JAVA 中所建议)不起作用!即:
RestClientBuilder builder = RestClient.builder (HttpHost.create (esURL))
.setHttpClientConfigCallback (hacb -> hacb.addInterceptorLast (interceptor));
highLevelClient = new RestHighLevelClient (builder);
总是导致来自 AWS 的以下错误消息:
{"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."}
我推测 ES 高级 rest 客户端构造了 AWS 拦截器在创建签名时看不到的 JSON 查询。由于等效方法适用于 Elastic Co 云实例(参见上面提到的 SO 线程),我猜这是 AWS 人员和 ES 人员不互相交谈的地方。
有什么方法可以使用 AWS CredentialsProvider 和 Signer,但使用 Apache HttpAsyncClientBuilder::setDefaultCredentialProvider 方法?或者是否有 ES Rest API 的一个版本,其中 Java 高级 Rest 客户端在 AWS 拦截器签名之前完全构建请求?
否则,我将被迫使用 IP 地址签名(呃),开始使用 Low Level Rest Client(双重呃),或者使用 ssh 隧道和 AWS VPC 安全的某种组合(许多呃)。
最佳答案
好的,我找到了一个目前适合我的答案。我找到了 aws-es-proxy 1在 github 上,它让我可以在我的机器上运行代理服务器。我通过 127.0.0.1:9200(可配置)连接到它,它签署我的请求并将其转发到我的 aws es 服务器。有效!
不过,它确实会向我的应用程序添加外部依赖项,因此总的来说,我认为这是一种变通方法,而不是解决方案。
关于java - Elasticsearch on AWS 用户身份验证,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51313147/