【问题标题】:Android Retrofit Request Using AWS Signature Authorization使用 AWS 签名授权的 Android 改造请求
【发布时间】:2018-10-25 10:19:50
【问题描述】:

我正在尝试从需要处理 aws-authentication 的 API 获取数据,我的问题是如何生成 Authorization 和 X-Amz-Date? 我必须将 3 个参数作为标题传递:Content-TypeAuthorizationX-Amz-Date。 如图所示:

这里是生成Authorization字符串的函数:

public static String gerateOAuthAWS(Context co) throws Exception {
    JodaTimeAndroid.init(co);
    DateTimeFormatter fmt = DateTimeFormat.forPattern("EEE', 'dd' 'MMM' 'yyyy' 'HH:mm:ss' 'Z").withLocale(Locale.US);
    String ZONE = "GMT";
    DateTime dt = new DateTime();
    DateTime dtLondon = dt.withZone(DateTimeZone.forID(ZONE)).plusHours(1);
    String formattedDate = dtLondon.toString(fmt);
    String oauth = "AWS4-HMAC-SHA256 Credential="+ ACCESS_KEY+"/us-east-1/execute-api/aws4_request, SignedHeaders=content-type;host;x-amz-date, Signature="+
            getSignatureKey(SECRET_KEY,formattedDate,"us-east-1","execute-api");
    return  oauth;
}


static byte[] HmacSHA256(String data, byte[] key) throws Exception {
    String algorithm="HmacSHA256";
    Mac mac = Mac.getInstance(algorithm);
    mac.init(new SecretKeySpec(key, algorithm));
    return mac.doFinal(data.getBytes("UTF8"));
}

static String getSignatureKey(String key, String dateStamp, String regionName, String serviceName) throws Exception {
    byte[] kSecret = ("AWS4" + key).getBytes("UTF8");
    byte[] kDate = HmacSHA256(dateStamp, kSecret);
    byte[] kRegion = HmacSHA256(regionName, kDate);
    byte[] kService = HmacSHA256(serviceName, kRegion);
    byte[] kSigning = HmacSHA256("aws4_request", kService);
    return Base64.encodeToString(kSigning,Base64.DEFAULT).replaceAll("\n", "");
}

Content-Type 是“application/x-www-form-urlencoded” 并生成 X-Amz-Date 内容为:“201805138T120046Z”

然后通过改造方法传递它们:

@GET("prod/video")
Call<ArrayList<Video>> getAllVideos(@Header("Content-Type")String content_type,
                                    @Header("X-Amz-Date")String amz_date,
                                    @Header("Authorization")String auth);

结果返回 null,我确定问题与授权有关,因为它以前运行良好。

感谢您的帮助:)

【问题讨论】:

  • 你能详细说明你的问题并提供更多细节和代码sn-p吗?您使用的是什么版本的 SDK?
  • @Karthikeyan 现在我更新它,提前谢谢。

标签: android amazon-web-services authentication retrofit aws-sdk


【解决方案1】:

我总是对我的朋友说,如果你觉得它看起来很复杂,你为什么要使用 retrofit 或 valley !

您可以使用 JSOUP 或 OKHTTP,这更容易,我真的很喜欢 JSOUP

您可以连接并向您发送数据的示例:

private void fcmIdentity(final String fcmKey) {
    new Thread(new Runnable() {
      @Override
      public void run() {
        try {
          SSLHelper.enableSSLSocket();
          Connection.Response response = Jsoup
            .connect(Urls.identity)
            .header("Accept", "application/json")
            .header("KEY_2", "VALUE_2")
            .method(Connection.Method.POST)
            .ignoreContentType(true)
            .ignoreHttpErrors(true)
            .validateTLSCertificates(true)
            .followRedirects(true)
            .data("fcm", "" + fcmKey)
            .data("identity", preferences.getString("FCM_ID", ""))
            .execute();

          Log.i("fcmIdentity", response.statusCode() + "");
          Log.i("fcmIdentity", response.toString());
          Log.d("fcmIdentity", response.headers().toString());
          Log.i("fcmIdentity", response.body());


        } catch (Exception e) {
          e.printStackTrace();
          if (e instanceof IOException) {
            G.toast(getString(R.string.connection_error), true);
          }
        }
      }
    }).start();
  }

关于 SSLHelper 帮助连接到 HTTPS 更多信息请查看我的主题https://answers.uncox.com/android/question/13003

【讨论】:

  • 这与问题无关,因为它说明了如何生成 AWS 签名授权。您没有生成任何授权,而且 Jsoup 和 Okhttp 也没有让事情变得更容易,实际上是相反的。它使响应的解析变得复杂(您需要将其映射到 JSONObject、循环等),不像 Retrofit 会自动将 JSON 响应响应到对象。
猜你喜欢
  • 2022-08-20
  • 1970-01-01
  • 2021-10-13
  • 2015-03-08
  • 2020-05-14
  • 1970-01-01
  • 2017-12-25
  • 2022-10-18
  • 2015-04-04
相关资源
最近更新 更多