代码之家  ›  专栏  ›  技术社区  ›  mjj1409

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

  •  1
  • mjj1409  · 技术社区  · 6 年前

    我得到一个http 403 forbidden 尝试删除 aws elasticsearch 通过java索引 Jest(v6.3) 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.
    

    我签了 aws 阿帕奇httpclient 用一个拦截器来签名请求 Spring Framework @Configuration 连接java的类 Jest

    @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();
        }
    }
    

    因为它是和邮递员一起工作的,所以它指出了一个签名错误,但我不知道哪里出现了不符。以上配置适用于所有人 阿帕奇httpclient 除了http删除请求之外的请求。

    1 回复  |  直到 6 年前
        1
  •  1
  •   mjj1409    6 年前

    经过一系列的研究,我发现了一些线索,指出 Content-Length 内容长度 但自从我们发送 内容长度 头到aws服务器,它正在将其分解,从而导致签名不匹配。我相信是这样的,因为我添加了一个额外的拦截器(在AWS签名拦截器之前),它显式地删除了 标题 DELETE 请求,请求成功通过。(即我可以删除索引)。更新代码如下:

    @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();
        }
    }