AppSync Java 使用 IAM 进行身份验证

AppSync Java authenticate with IAM

我正在尝试更新我的 appsync 客户端以使用 IAM 凭据进行身份验证。在 API_KEY 的情况下,我像这样设置 API_KEY_HEADER: request.addHeader(API_KEY_HEADER, this.apiKey); 是否有类似的方法在 Java 客户端中使用 IAM 凭据进行身份验证?是否有 header 我可以像这里一样传递秘密和访问密钥:https://docs.amplify.aws/lib/graphqlapi/authz/q/platform/js#iam?或者我应该只使用 cognito 用户池来验证请求吗?

根据 AWS 文档,我们需要使用此处记录的过程来使用签名请求:https://docs.aws.amazon.com/general/latest/gr/signature-version-4.html and steps listed here: 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());

}