Я отправляю json в AWS elasticsearch, используя функцию лямбда java.Почему я получаю 403 запрещенную ошибку при отправке json в конечную точку elasticsearch на AWS?
public Object handleRequest(DynamodbEvent dynamodbEvent, Context context) {
//code to general the json document
AmazonDynamoDBClient amazonDynamoDBClient = new AmazonDynamoDBClient();
List<DynamodbEvent.DynamodbStreamRecord> dynamodbStreamRecordlist = dynamodbEvent.getRecords();
if (!dynamodbStreamRecordlist.isEmpty()) {
DynamodbEvent.DynamodbStreamRecord record = dynamodbStreamRecordlist.get(0);
if(record.getEventSource().equalsIgnoreCase("aws:dynamodb"))
tableName = getTableNameFromARN(record.getEventSourceARN());
}
LaneAnnotation laneAnnotation = new LaneAnnotation();
ScanRequest scanRequest = new ScanRequest().withTableName(tableName);
ScanResult result = amazonDynamoDBClient.scan(scanRequest);
List<Lines> linesFinalList = new ArrayList<Lines>();
if(result != null) {
for (Map<String, AttributeValue> item : result.getItems()) {
//code for looping through the table items and generating a json object for the elastic search model
}
//Code to post the json below -
RestTemplate restTemplate = new RestTemplate();
SimpleClientHttpRequestFactory clientHttpRequestFactory = (SimpleClientHttpRequestFactory)restTemplate.getRequestFactory();
clientHttpRequestFactory.setConnectTimeout(10000);
clientHttpRequestFactory.setReadTimeout(10000);
HttpEntity<String> entity = new HttpEntity<String>(<json goes here>, headers);
try{
restTemplate.exchange(endpoint, HttpMethod.POST, entity, String.class);
}catch(Exception e){
e.printStackTrace();
}
}
Однако, я вижу следующее сообщение об ошибке, когда я проверить свою функцию лямбда-AWS -
org.springframework.web.client.HttpClientErrorException: 403 Forbidden
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
at com.here.aws.LambdaApplication.handleRequest(LambdaApplication.java:166)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at lambdainternal.EventHandlerLoader$PojoMethodRequestHandler.handleRequest(EventHandlerLoader.java:456)
at lambdainternal.EventHandlerLoader$PojoHandlerAsStreamHandler.handleRequest(EventHandlerLoader.java:375)
at lambdainternal.EventHandlerLoader$2.call(EventHandlerLoader.java:1139)
at lambdainternal.AWSLambda.startRuntime(AWSLambda.java:285)
at lambdainternal.AWSLambda.<clinit>(AWSLambda.java:57)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at lambdainternal.LambdaRTEntry.main(LambdaRTEntry.java:94)
Я даже изменил политику доступа и добавил свой IP-адрес. Неужели другие тоже сталкиваются с этим? Как вы его разрешили?> Любая помощь будет оценена.
EDIT1: Я сейчас пытаюсь включить подписание запроса, как указано здесь - https://aws.amazon.com/blogs/security/how-to-control-access-to-your-amazon-elasticsearch-service-domain/
доложит, если она идет хорошо.
EDIT2:
Вот второй способ отправки запроса, который я пытался со ссылкой на ссылку выше-
@Override
public Object handleRequest(DynamodbEvent dynamodbEvent, Context context) {
AmazonDynamoDBClient amazonDynamoDBClient = new AmazonDynamoDBClient();
List<DynamodbEvent.DynamodbStreamRecord> dynamodbStreamRecordlist = dynamodbEvent.getRecords();
if (!dynamodbStreamRecordlist.isEmpty()) {
DynamodbEvent.DynamodbStreamRecord record = dynamodbStreamRecordlist.get(0);
if(record.getEventSource().equalsIgnoreCase("aws:dynamodb"))
tableName = getTableNameFromARN(record.getEventSourceARN());
}
LaneAnnotation laneAnnotation = new LaneAnnotation();
ScanRequest scanRequest = new ScanRequest().withTableName(tableName);
ScanResult result = amazonDynamoDBClient.scan(scanRequest);
List<Lines> linesFinalList = new ArrayList<Lines>();
if(result != null) {
for (Map<String, AttributeValue> item : result.getItems()) {
//Generate the json object that needs to be sent in the request
}
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON_UTF8);
Request<?> request = new DefaultRequest<Void>(SERVICE_NAME);
request.setContent(new ByteArrayInputStream(elasticSearchModel.toString().getBytes()));
request.setEndpoint(URI.create(endpoint));
request.setHttpMethod(HttpMethodName.POST);
AWS4Signer signer = new AWS4Signer();
signer.setServiceName(SERVICE_NAME);
signer.setRegionName(Regions.US_EAST_1.getName());
AWSCredentialsProvider credsProvider =
new DefaultAWSCredentialsProviderChain();
AWSCredentials creds = credsProvider.getCredentials();
// Sign request with supplied creds
signer.sign(request, creds);
log.info("Request signed");
ExecutionContext executionContext = new ExecutionContext(true);
ClientConfiguration clientConfiguration = new ClientConfiguration();
AmazonHttpClient client = new AmazonHttpClient(clientConfiguration);
MyHttpResponseHandler<Void> responseHandler = new MyHttpResponseHandler<Void>();
MyErrorHandler errorHandler = new MyErrorHandler();
Response<Void> response =
client.execute(request, responseHandler, errorHandler, executionContext);
return dynamodbEvent;
}
Однако, я получаю следующее сообщение об ошибке -
Check the signature you provided. Check your AWS Secret Access Key and signing method. Consult the service documentation for details.
The Canonical String for this request should have been
'GET
/
host:somehostname-XXXXXXXXXXXXXXXX.us-east-1.es.amazonaws.com
x-amz-date:20170130T105736Z
x-amz-security-token:FQoDYXdzEG4aDJJ4ryjXXXXXXXXXXXXXXXX/auMHooYENY6YXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
host;x-amz-date;x-amz-security-token
e3b0c4429XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
The String-to-Sign should have been
'AWS4-HMAC-SHA256
20170130T105736Z
20170130/us-east-1/es/aws4_request
9a5b4c92ec121c333f8cdXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
"}"
10:57:36.818 [main] DEBUG org.apache.http.headers - http-outgoing-1 << HTTP/1.1 403 Forbidden
Может быть несколько вещей, которые могут вызвать это. Индекс ors устанавливается только для чтения (то есть когда ES сам возвращает 403), или если вы используете прокси перед ним или у вас нет доступа к записи в этот индекс. – chaos
Это потому, что мне нужно добавить аутентификацию в запрос? Я просто загружаю свою банку лямбды на s3 и использую ее url для проверки моей лямбда-функции. Я добавил еще один код выше, чтобы показать, как я извлекаю элементы из своей таблицы. –
Просто нашел это - https://aws.amazon.com/blogs/security/how-to-control-access-to-your-amazon-elasticsearch -service-domain/Позвольте мне попробовать, и я обновляю здесь, как это произошло. –