我正在尝试使用okhttp在android中为aws api网关签署一个http请求。我或多或少地使用了此stackoverflow问题stackoverflow question
中的代码我使用CognitoCachingCredentialsProvider()来获取credentialsProvider对象。然后我使用getCredentials()来获取凭据。然后,我使用以下内容:credentials.getAWSAccessKeyId(),credentials.getAWSSecretKey()和credentials.getSessionToken()来获取必要的密钥和令牌。我在邮递员中使用它们并且能够成功执行api网关。
使用okhttp在android中请求失败,返回带有消息" Missing Authentication Token"的代码403。
这就是我准备请求的方法:我构建一个DefaultRequest对象,设置端点和httpmethod。然后,我使用AWS4Signer对请求进行签名,将凭证对象作为signer.sign(defaultRequest,credentials)参数传递。
我通过在defaultRequest上调用getHeaders()来获取标题的映射。我创建了两个列表,一个名为密钥,一个名称为值。然后我遍历地图,将密钥和相应的值加载到两个列表中。
然后我按照以下方式构建我的okhttp请求:Request request = new Request.Builder()
.url(my ApiEndPoint)
.addHeader(key.get(0), value.get(0))
.addHeader(key.get(1), value.get(1))
.addHeader(key.get(2), value.get(2))
.addHeader(key.get(3), value.get(3))
.addHeader("Content-Type", "application/x-www-form-urlencoded")
.post(body)
.build();
我注意到以下内容:
在标题地图中,键 x-amz-security-token 有一个值....以 hKADF87VZ44w9IvZ1gU =
结尾打印出okhttp请求, x-amz-security-token 键有一个值....以 hKADF87VZ44w9IvZ1gU \ u003d
结尾=被替换为\ u003d,这可能是问题吗?如果是这样,如何防止这种情况?
否则,我们将非常感谢您解决此问题的任何帮助。
感谢
答案 0 :(得分:1)
设法解决问题。似乎将标题分配给OkHttp请求是问题所在。所以这是我的代码:
我首先获得AWSSessionCredentials凭据。然后:
AmazonWebServiceRequest amazonWebServiceRequest = new AmazonWebServiceRequest() {
};
String API_GATEWAY_SERVICE_NAME = "execute-api";
com.amazonaws.Request requestAws = new DefaultRequest(amazonWebServiceRequest, API_GATEWAY_SERVICE_NAME);
您可以使用服务端点:
URI uri = URI.create("https://apigateway.eu-west-1.amazonaws.com");
或您的api url(根据Api Gateway控制台阶段选项(已部署的api)调用api的url):
String invokeUrl = "https://xxxx.execute-api.eu-west-1.amazonaws.com/yyy/zzzzz";
// using the invoke url
URI uri = URI.create(invokeUrl);
requestAws.setEndpoint(uri);
requestAws.setResourcePath(invokeUrl);
requestAws.setHttpMethod(HttpMethodName.POST);
现在签署请求
AWS4Signer signer = new AWS4Signer();
signer.setServiceName(API_GATEWAY_SERVICE_NAME);
signer.setRegionName(Region.getRegion(Regions.EU_WEST_1).getName());
signer.sign(requestAws, credentials);
获取标题
// get map of headers
Map<String, String> headers = requestAws.getHeaders();
// create objects for the headers to add manually in OkHttp request builder
String x_date = null;
String x_token = null;
String authorization = null;
//get and assign values
for (Map.Entry<String, String> entry : headers.entrySet()) {
if (entry.getKey().equals("x-amz-security-token")) {
x_token = entry.getValue();
}
if (entry.getKey().equals("X-Amz-Date")) {
x_date = entry.getValue();
}
if (entry.getKey().equals("Authorization")) {
authorization = entry.getValue();
}
}
构建OkHttp请求:
Request request = new Request.Builder()
.url(invokeUrl)
.addHeader("Content-Type", "application/json")
.addHeader("X-Amz-Date", x_date)
.addHeader("x-amz-security-token", x_token)
.addHeader("Authorization", authorization)
.post(body)
.build();
现在拨打你的OkHttp电话。
希望这对某人有帮助。