我正在尝试使用具有临时凭据的Rest Api从我的Android应用程序下载存储在AWS中的S3存储桶中的图像。我需要使用其余API而不是Android AWS SDK中包含的TransferUtility方法,因为我想使用图像下载器来获得更好的性能。根据官方AWS文档,我需要向HTTP Get请求添加一个Authorization标头,这样符合:
Authorization = "AWS" + " " + AWSAccessKeyId + ":" + Signature;
Signature = Base64( HMAC-SHA1( YourSecretAccessKeyID, UTF-8-Encoding-Of( StringToSign ) ) );
StringToSign = HTTP-Verb + "\n" +
Content-MD5 + "\n" +
Content-Type + "\n" +
Date + "\n" +
CanonicalizedAmzHeaders +
CanonicalizedResource;
所以,我获得了这样的Authorization标题:
public String AuthorizationHeader (String dirToImageInBucket) throws UnsupportedEncodingException {
final AWSMobileClient mobileClient = AWSMobileClient.defaultMobileClient();
IdentityManager iM = mobileClient.getIdentityManager();
AWSCredentialsProvider sCredProvider= iM.getCredentialsProvider();
String secretKey = sCredProvider.getCredentials().getAWSSecretKey();
String awsAccessKeyId = sCredProvider.getCredentials().getAWSAccessKeyId();
Mac hmac = null;
hmac = Mac.getInstance("HmacSHA1");
hmac.init(new SecretKeySpec(secretKey.getBytes("UTF-8"), "HmacSHA1"));
Date dateT = new Date();
@SuppressLint("SimpleDateFormat") DateFormat dateFormat = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss Z");
String date = dateFormat.format(dateT);
String token = "x-amz-security-token:" + Login_Related.geToken(activity) +"\nx-amz-date:" +date+"\n";
String stringToSign = "GET" + "\n\n\n" + date + "\n" + token + "/" + dirToImageInBucket;
String signature = ( Base64.encodeToString(hmac.doFinal(stringToSign.getBytes("UTF-8")), Base64.DEFAULT)).replaceAll("\n", "");
return "AWS" + " " + awsAccessKeyId + ":" + signature;
}
然后我将前一个方法返回的“Authorization”标头添加到HTTP GET请求中,并且还在请求中包含标头x-amz-date和x-amz-security-token(具有日期值)和临时访问令牌)。我目前正在测试Postman上的请求来测试我是否可以通过将所提到的标题添加到图像URL的GET请求来下载图像,每次我发送它时,我都会得到响应:
<Error>
<Code>InvalidToken</Code>
<Message>The provided token is malformed or otherwise invalid.</Message>
<Token-0>eyJraWQiOiJ4TFYxcVZiNG1IY3IrSWUxS....
我确信我使用的是正确的令牌,因为我的应用中的其他http请求正在使用该令牌。任何人都可以帮我理解我错过了什么或做错了什么?感谢。
编辑包含令牌方法:
static public String geToken(Activity act) {
AWSMobileClient.initializeMobileClientIfNecessary(act.getApplicationContext());
final AWSMobileClient mobileClient = AWSMobileClient.defaultMobileClient();
IdentityManager iM = mobileClient.getIdentityManager();
IdentityProvider iP = iM.getCurrentIdentityProvider();
token = iP.refreshToken();
System.out.println("x-amz-security-token check this token: " + token);
return token;
}