调用 AWS API - 签名、身份验证 Header - 在 android 中使用 OkHTTP
Calling AWS API - Signature, Authentication Header - using OkHTTP in android
我正在尝试使用 OkHTTP 在 android 中签署对 AWS API 的 HTTP 请求。我使用了这个 中的代码。 AWS 的文档一点帮助也没有。我很困扰。这是迄今为止我找到的唯一易于理解和实现的代码。但这也不适用于我的问题。我没有通过 API 传递任何数据,它只是简单的 API,我必须调用它并接收消息。
我的代码
AWSCredentials credentials = new BasicAWSCredentials(access_key_id.trim(), secret_access_key.trim());
String API_GATEWAY_SERVICE_NAME = "execute-api";
Request requestAws = new DefaultRequest(API_GATEWAY_SERVICE_NAME);
URI uri = URI.create(url);
requestAws.setEndpoint(uri);
requestAws.setResourcePath(url);
requestAws.setHttpMethod(HttpMethodName.POST);
AWS4Signer signer = new AWS4Signer();
signer.setServiceName(API_GATEWAY_SERVICE_NAME);
signer.setRegionName("us-east-2");
signer.sign(requestAws, credentials);
OkHttpClient httpClient = new OkHttpClient();
Map<String, String> headers = requestAws.getHeaders();
List<String> key = new ArrayList<String>();
List<String> value = new ArrayList<String>();
for (Map.Entry<String, String> entry : headers.entrySet()) {
key.add(entry.getKey());
value.add(entry.getValue());
}
okhttp3.Request request = new okhttp3.Request.Builder()
.url(url)
.addHeader(key.get(0), value.get(0))
.addHeader(key.get(1), value.get(1))
.addHeader(key.get(2), value.get(2))
.build();
Response response = httpClient.newCall(request).execute();
错误我得到
{"message":"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.\n\nThe Canonical String for this request should have been\n'GET\n/**2nd last part of url ***/**last part of url ***/\n\nhost:***.execute-api.us-east-2.amazonaws.com\nx-amz-date:20210306T082609Z\n\nhost;x-amz-date\***signature***'\n\nThe String-to-Sign should have been\n'AWS4-HMAC-SHA256\n20210306T082609Z\n20210306/us-east-2/execute-api/aws4_request\n***signature***'\n"}
这是一个简单的代码,但我找不到任何问题。服务器错误也无济于事。
从服务器端我没有使用任何 content-type 这就是为什么我没有在 header 中传递它。这可能是个问题吗?我也认为我的 requesAws 有问题。
可能是这一行有问题。我不知道这到底是什么意思,所以我在其中传递了与引用代码相同的 API url。
requestAws.setResourcePath(url);
我不建议您编写自己的 SigV4 签名器。相反,尝试拉取一个作为库依赖项。
dependencies {
implementation 'com.github.babbel:okhttp-aws-signer:1.0.1'
}
val signer = OkHttpAwsV4Signer("us-east-1", "execute-api")
val client = OkHttpClient.Builder()
.addInterceptor { chain ->
val original = chain.request()
val signed = signer.sign(original, accessKeyId, accessKey)
chain.proceed(signed)
}
.build()
repositories {
maven {
url "http://dl.bintray.com/ghedeon/maven"
}
}
...
dependencies {
implementation 'com.ghedeon:aws-interceptor:0.6'
}
val interceptor = AwsInterceptor(credentialsProvider, serviceName, region)
val okHttpClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build()
后者uses the AWS Android SDK under the hood。如果您使用的是 Amazon Cognito,则可以为 credentialsProvider
参数提供 AWSMobileClient.getInstance()
。
val okHttpClient = new OkHttpClient.Builder()
.addInterceptor(AwsInterceptor(
AWSMobileClient.getInstance(), "execute-api", "us-east-1"
))
.build()
我正在尝试使用 OkHTTP 在 android 中签署对 AWS API 的 HTTP 请求。我使用了这个
我的代码
AWSCredentials credentials = new BasicAWSCredentials(access_key_id.trim(), secret_access_key.trim());
String API_GATEWAY_SERVICE_NAME = "execute-api";
Request requestAws = new DefaultRequest(API_GATEWAY_SERVICE_NAME);
URI uri = URI.create(url);
requestAws.setEndpoint(uri);
requestAws.setResourcePath(url);
requestAws.setHttpMethod(HttpMethodName.POST);
AWS4Signer signer = new AWS4Signer();
signer.setServiceName(API_GATEWAY_SERVICE_NAME);
signer.setRegionName("us-east-2");
signer.sign(requestAws, credentials);
OkHttpClient httpClient = new OkHttpClient();
Map<String, String> headers = requestAws.getHeaders();
List<String> key = new ArrayList<String>();
List<String> value = new ArrayList<String>();
for (Map.Entry<String, String> entry : headers.entrySet()) {
key.add(entry.getKey());
value.add(entry.getValue());
}
okhttp3.Request request = new okhttp3.Request.Builder()
.url(url)
.addHeader(key.get(0), value.get(0))
.addHeader(key.get(1), value.get(1))
.addHeader(key.get(2), value.get(2))
.build();
Response response = httpClient.newCall(request).execute();
错误我得到
{"message":"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.\n\nThe Canonical String for this request should have been\n'GET\n/**2nd last part of url ***/**last part of url ***/\n\nhost:***.execute-api.us-east-2.amazonaws.com\nx-amz-date:20210306T082609Z\n\nhost;x-amz-date\***signature***'\n\nThe String-to-Sign should have been\n'AWS4-HMAC-SHA256\n20210306T082609Z\n20210306/us-east-2/execute-api/aws4_request\n***signature***'\n"}
这是一个简单的代码,但我找不到任何问题。服务器错误也无济于事。
从服务器端我没有使用任何 content-type 这就是为什么我没有在 header 中传递它。这可能是个问题吗?我也认为我的 requesAws 有问题。
可能是这一行有问题。我不知道这到底是什么意思,所以我在其中传递了与引用代码相同的 API url。
requestAws.setResourcePath(url);
我不建议您编写自己的 SigV4 签名器。相反,尝试拉取一个作为库依赖项。
dependencies {
implementation 'com.github.babbel:okhttp-aws-signer:1.0.1'
}
val signer = OkHttpAwsV4Signer("us-east-1", "execute-api")
val client = OkHttpClient.Builder()
.addInterceptor { chain ->
val original = chain.request()
val signed = signer.sign(original, accessKeyId, accessKey)
chain.proceed(signed)
}
.build()
repositories {
maven {
url "http://dl.bintray.com/ghedeon/maven"
}
}
...
dependencies {
implementation 'com.ghedeon:aws-interceptor:0.6'
}
val interceptor = AwsInterceptor(credentialsProvider, serviceName, region)
val okHttpClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.build()
后者uses the AWS Android SDK under the hood。如果您使用的是 Amazon Cognito,则可以为 credentialsProvider
参数提供 AWSMobileClient.getInstance()
。
val okHttpClient = new OkHttpClient.Builder()
.addInterceptor(AwsInterceptor(
AWSMobileClient.getInstance(), "execute-api", "us-east-1"
))
.build()