Android Retrofit请求如何生成AWS授权的Authorization与X-Amz-Date
Let's break down the potential issues with your AWS signature generation and request setup—these are likely the root causes of your empty response:
1. Critical Time & Date Format Mistakes
AWS signature validation is extremely strict about timestamps, and your current code has a few red flags here:
- Wrong X-Amz-Date Format: Your example
201805138T120046Zis invalid. The correct ISO 8601 format required forX-Amz-DateisYYYYMMDD'T'HHMMSS'Z'(e.g.,20180513T120046Z). - Incorrect Time Zone Handling: You're converting to GMT and then adding 1 hour with
plusHours(1)—AWS requires all timestamps to be UTC (GMT) time with no offsets. Remove this extra hour adjustment. - Mismatched Date Values: Your code passes a formatted date string (like
Mon, 13 May 2018 12:00:00 GMT) togetSignatureKey, but this function expects adateStampinYYYYMMDDformat. You need to generate two distinct date values:// Generate UTC time DateTime utcTime = new DateTime(DateTimeZone.UTC); // For Credential in Authorization header String dateStamp = utcTime.toString("yyyyMMdd"); // For X-Amz-Date header String xAmzDate = utcTime.toString("yyyyMMdd'T'HHmmss'Z'");
2. Missing Required Request Header
Your Authorization header lists host in SignedHeaders, but your Retrofit interface doesn't include the Host header. AWS requires every header specified in SignedHeaders to be present in the request. Add it to your interface:
@GET("prod/video") Call<ArrayList<Video>> getAllVideos( @Header("Content-Type") String content_type, @Header("X-Amz-Date") String amz_date, @Header("Authorization") String auth, @Header("Host") String host); // Add this line
The Host value should be your API Gateway's full domain (e.g., xxxx.execute-api.us-east-1.amazonaws.com).
3. Signature Generation Fixes
- Base64 Encoding: Using
Base64.DEFAULTadds unnecessary line breaks. Switch toBase64.NO_WRAPto avoid formatting issues:return Base64.encodeToString(kSigning, Base64.NO_WRAP); - Credential Path Format: Ensure your
Credentialsegment in theAuthorizationheader uses theYYYYMMDDdateStamp, not the formatted date string. Update yourgerateOAuthAWSfunction to use the correctdateStamp:String oauth = "AWS4-HMAC-SHA256 Credential="+ ACCESS_KEY+"/"+dateStamp+"/us-east-1/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature="+ getSignatureKey(SECRET_KEY,dateStamp,"us-east-1","execute-api");
4. Debugging Tip
Enable CloudWatch Logs for your API Gateway—this will show detailed error messages like "Signature expired" or "Signature does not match", which will help you pinpoint exactly where the validation is failing.
内容的提问来源于stack exchange,提问作者Mahsa

