我正在尝试更新我的appsync客户端以使用IAM凭据进行身份验证。在使用API_KEY的情况下,我可以这样设置API_KEY_HEADER:request.addHeader(API_KEY_HEADER, this.apiKey);
是否可以使用IAM凭据在Java客户端中进行身份验证的类似方法?我可以传递一个头来传递秘密和访问密钥,例如:https://docs.amplify.aws/lib/graphqlapi/authz/q/platform/js#iam吗?还是我应该使用认知用户池来验证请求?
答案 0 :(得分:0)
根据AWS文档,我们需要使用https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html此处记录的流程和https://docs.aws.amazon.com/general/latest/gr/sigv4_signing.html此处列出的步骤来使用签名请求。 我还在这里找到一个实现:https://medium.com/@tridibbolar/aws-lambda-as-an-appsync-client-fbb0c1ce927d。使用上面的代码:
private void signRequest(final Request<AmazonWebServiceRequest> request) {
final AWS4Signer signer = new AWS4Signer();
signer.setRegionName(this.region);
signer.setServiceName("appsync");
signer.sign(request, this.appsyncCredentials);
}
private Request<AmazonWebServiceRequest> getRequest(final String data) {
final Request<AmazonWebServiceRequest> request =
new DefaultRequest<AmazonWebServiceRequest>("appsync");
request.setHttpMethod(HttpMethodName.POST);
request.setEndpoint(URI.create(this.appSyncEndpoint));
final byte[] byteArray = data.getBytes(Charset.forName("UTF-8"));
request.setContent(new ByteArrayInputStream(byteArray));
request.addHeader(AUTH_TYPE_HEADER, AWS_IAM_AUTH_TYPE);
request.addHeader(HttpHeaders.CONTENT_TYPE, APPLICATION_GRAPHQL);
request.addHeader(HttpHeaders.CONTENT_LENGTH, String.valueOf(byteArray.length));
signRequest(request);
return request;
}
private HttpResponseHandler<String> getResponseHandler() {
final HttpResponseHandler<String> responseHandler = new HttpResponseHandler<String>() {
@Override
public String handle(com.amazonaws.http.HttpResponse httpResponse) throws Exception {
final String result = IOUtils.toString(httpResponse.getContent());
if(httpResponse.getStatusCode() != HttpStatus.SC_OK) {
final String errorText = String.format(
"Error posting request. Response status code was %s and text was %s. ",
httpResponse.getStatusCode(),
httpResponse.getStatusText());
throw new RuntimeException(errorText);
} else {
final ObjectMapper objectMapper = new ObjectMapper();
//custom class to parse appsync response.
final AppsyncResponse response = objectMapper.readValue(result, AppsyncResponse.class);
if(CollectionUtils.isNotEmpty(response.getErrors())){
final String errorMessages = response
.getErrors()
.stream()
.map(Error::getMessage)
.collect(Collectors.joining("\n"));
final String errorText = String.format(
"Error posting appsync request. Errors were %s. ",
errorMessages);
throw new RuntimeException(errorText);
}
}
return result;
}
@Override
public boolean needsConnectionLeftOpen() {
return false;
}
};
return responseHandler;
}
private Response<String> makeGraphQlRequest(final Request<AmazonWebServiceRequest> request) {
return this.httpClient.requestExecutionBuilder()
.executionContext(new ExecutionContext())
.request(request)
.execute(getResponseHandler());
}