AppSync Java通过IAM进行身份验证

时间:2020-06-16 05:57:52

标签: amazon-web-services aws-appsync

我正在尝试更新我的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吗?还是我应该使用认知用户池来验证请求?

1 个答案:

答案 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());

}