gpt4 book ai didi

spring-boot - aws elasticsearch 签名删除请求返回 403 forbidden(使用 apache httpclient)

转载 作者:行者123 更新时间:2023-12-04 17:43:59 29 4
gpt4 key购买 nike

我在尝试通过 java Jest(v6.3) 删除 aws elasticsearch 索引时收到 http 403 forbidden 错误elasticsearch 客户端(它将 http 调用委托(delegate)给 apache httpclient(v4.5.2) 我知道我的权限在 AWS 中设置正确,因为我能够成功使用 postman (在 AWS 签名授权助手的帮助下)。但是,使用 apache httpclient,当我发出 DELETE/{myIndexName} 时,我收到以下错误:

    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.

我通过使用签名请求的拦截器配置 apache httpclient 来签署 aws 请求。(下面的代码适用于 Spring Framework @ Configuration 连接 java Jest 客户端和底层 apache httpclient 的类)但我想如果我直接使用 apache httpclient 我会遇到同样的问题。

@Configuration
public class ElasticSearchConfiguration {

@Autowired
private CredentialsProviderFactoryBean awsCredentialsProvider;

@Bean
public JestClient awsJestClient(@Value("${elasticsearch.url}") String connectionUrl) throws Exception {
com.amazonaws.auth.AWSCredentialsProvider provider = awsCredentialsProvider.getObject();

final com.google.common.base.Supplier<LocalDateTime> clock = () -> LocalDateTime.now(ZoneOffset.UTC);
final vc.inreach.aws.request.AWSSigner awsSigner = new vc.inreach.aws.request.AWSSigner(provider, "us-east-1", "es", clock);
final vc.inreach.aws.request.AWSSigningRequestInterceptor requestInterceptor = new vc.inreach.aws.request.AWSSigningRequestInterceptor(awsSigner);


final JestClientFactory factory = new JestClientFactory() {
@Override
protected HttpClientBuilder configureHttpClient(HttpClientBuilder builder) {
builder.addInterceptorLast(requestInterceptor);
return builder;
}
@Override
protected HttpAsyncClientBuilder configureHttpClient(HttpAsyncClientBuilder builder) {
builder.addInterceptorLast(requestInterceptor);
return builder;
}
};

factory.setHttpClientConfig(new HttpClientConfig
.Builder(connectionUrl)
.connTimeout(60000)
.multiThreaded(true)
.build());

return factory.getObject();
}
}

由于它与 postman 合作,它指出了签名错误,但我不知道哪里出现了差异。上面的配置适用于除 http DELETE 请求之外的所有 apache httpclient 请求。

最佳答案

经过一系列研究后,我发现了一些线索,这些线索指出了向 aws 发出的请求中 Content-Length (length=0) 的存在导致签名不匹配的可能性。我猜测通过客户端拦截器完成的签名没有考虑 Content-Length header ,但由于我们将 Content-Length header 发送到 aws 服务器,它将其考虑在内,从而导致签名不匹配。我相信是这种情况,因为我添加了一个额外的拦截器(在 AWS 签名拦截器之前),它明确删除了 DELETE 请求的 Content-Length header 并且请求通过成功地。 (即我能够删除索引)。更新代码如下:

@Configuration
public class ElasticSearchConfiguration {
private static final Logger log = LoggerFactory.getLogger(ElasticSearchConfiguration.class);
@Autowired
private CredentialsProviderFactoryBean awsCredentialsProvider;


@Bean
public JestClient awsJestClient(@Value("${elasticsearch.url}") String connectionUrl) throws Exception {
com.amazonaws.auth.AWSCredentialsProvider provider = awsCredentialsProvider.getObject();

final com.google.common.base.Supplier<LocalDateTime> clock = () -> LocalDateTime.now(ZoneOffset.UTC);
final vc.inreach.aws.request.AWSSigner awsSigner = new vc.inreach.aws.request.AWSSigner(provider, "us-east-1", "es", clock);
final vc.inreach.aws.request.AWSSigningRequestInterceptor requestInterceptor = new vc.inreach.aws.request.AWSSigningRequestInterceptor(awsSigner);

final HttpRequestInterceptor removeDeleteMethodContentLengthHeaderRequestInterceptor = (request, context) -> {
if(request.getRequestLine().getMethod().equals("DELETE")) {
log.warn("intercepted aws es DELETE request, will remove 'Content-Length' header as it's presence invalidates the signature check on AWS' end");
request.removeHeaders("Content-Length");
}
};

final JestClientFactory factory = new JestClientFactory() {
@Override
protected HttpClientBuilder configureHttpClient(HttpClientBuilder builder) {
builder.addInterceptorLast(removeDeleteMethodContentLengthHeaderRequestInterceptor);
builder.addInterceptorLast(requestInterceptor);
return builder;
}
@Override
protected HttpAsyncClientBuilder configureHttpClient(HttpAsyncClientBuilder builder) {
builder.addInterceptorLast(removeDeleteMethodContentLengthHeaderRequestInterceptor);
builder.addInterceptorLast(requestInterceptor);
return builder;
}
};

factory.setHttpClientConfig(new HttpClientConfig
.Builder(connectionUrl)
.connTimeout(60000)
.multiThreaded(true)
.build());

return factory.getObject();
}
}

关于spring-boot - aws elasticsearch 签名删除请求返回 403 forbidden(使用 apache httpclient),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53064927/

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