如何从Java调用AmazonAWSAPI?

如何从Java调用AmazonAWSAPI?,java,amazon-web-services,rest,authorization,Java,Amazon Web Services,Rest,Authorization,如果我想从Java调用Amazon AWS Rest API,我的选项是什么 在实现我自己的请求时,生成AWS4-HMAC-SHA256授权头将是最困难的 本质上,这是我需要生成的标题: Authorization: AWS4-HMAC-SHA256 Credential=AKIAJTOUYS27JPVRDUYQ/20200602/us-east-1/route53/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date,

如果我想从Java调用Amazon AWS Rest API,我的选项是什么

在实现我自己的请求时,生成
AWS4-HMAC-SHA256
授权头将是最困难的

本质上,这是我需要生成的标题:

Authorization: AWS4-HMAC-SHA256 Credential=AKIAJTOUYS27JPVRDUYQ/20200602/us-east-1/route53/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=ba85affa19fa4a8735ce952e50d41c8c93406a11d22b88cc98b109b529bcc15e
POST https://route53.amazonaws.com/2013-04-01/hostedzone/Z08118721NNU878C4PBNA/rrset
Host: route53.amazonaws.com
X-Amz-Content-Sha256: 46c7521da55bcf9e99fa6e12ec83997fab53128b5df0fb12018a6b76fb2bf891
X-Amz-Date: 20200602T035618Z
Authorization: AWS4-HMAC-SHA256 Credential=AKIAJTOUYS27JPVRDUYQ/20200602/us-east-1/route53/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=6a59090f837cf71fa228d2650e9b82e9769e0ec13e9864e40bd2f81c682ef8cb
Content-Type: text/xml; charset=utf-8
<?xml version="1.0" encoding="UTF-8"?>
<ChangeResourceRecordSetsRequest xmlns="https://route53.amazonaws.com/doc/2013-04-01/">
<ChangeBatch>
   <Changes>
      <Change>
         <Action>UPSERT</Action>
         <ResourceRecordSet>
            <Name>c001cxxx.frusal.com.</Name>
            <Type>A</Type>
            <TTL>300</TTL>
            <ResourceRecords>
               <ResourceRecord>
                  <Value>157.245.232.185</Value>
               </ResourceRecord>
            </ResourceRecords>
         </ResourceRecordSet>
      </Change>
   </Changes>
</ChangeBatch>
</ChangeResourceRecordSetsRequest>
connection.getResponseCode()=200
responseContentType=text/xml
Response BODY:
<?xml version="1.0"?>
<ChangeResourceRecordSetsResponse xmlns="https://route53.amazonaws.com/doc/2013-04-01/"><ChangeInfo><Id>/change/C011827119UYGF04GVIP6</Id><Status>PENDING</Status><SubmittedAt>2020-06-02T03:56:25.822Z</SubmittedAt></ChangeInfo></ChangeResourceRecordSetsResponse>

<>不是说这是一个完整的列表,但是我会考虑使用诸如“

”这样的已建立的库。
  • 官方的,或-当前的和全面的,但取决于和许多其他罐
  • -依赖于JAXB,它不再是JDK的一部分,但现在可以在maven central单独使用
但有时,您只需要进行一个简单的调用,而不想在应用程序中引入许多依赖项。您可能希望自己实现其余的调用。生成正确的AWS授权头是最难实现的

下面是在没有外部依赖关系的纯java OpenJDK中实现这一点的代码

它实现了亚马逊AWS API签名版本4的签名过程

AmazonRequestSignatureV4Utils.java

package com.frusal.amazonsig4;
导入java.nio.charset.StandardCharset;
导入java.security.MessageDigest;
导入java.util.ArrayList;
导入java.util.List;
导入java.util.Map;
导入java.util.Map.Entry;
导入java.util.stream.collector;
导入javax.crypto.Mac;
导入javax.crypto.spec.SecretKeySpec;
公共类AmazonRequestSignatureV4Utils{
/**
*根据Amazon AWS API签名版本4流程为HTTP请求生成签名头。
*
*这里概述了以下步骤:
*
*简单的用法示例如下:{@link AmazonRequestSignatureV4Example}
*
*此方法将许多参数作为只读参数,但将必要的头添加到@{code headers}参数,该参数是一个映射。
*调用方应确保将这些参数复制到实际的请求对象。
*
*ISO8601日期参数可以通过调用来创建:
*-{@code java.time.format.DateTimeFormatter.of模式(“yyyyymmdd'T'HHmmss'Z')).format(ZoneDateTime.now(ZoneOffset.UTC))}
*或者,如果你喜欢乔达:
*-{@code org.joda.time.format.ISODateTimeFormat.basicdatetimenomilis().print(DateTime.now().withZone(DateTimeZone.UTC))} * *@param method-HTTP请求方法,(GET | POST | DELETE | PUT |…),例如,{@link java.net.HttpURLConnection#getRequestMethod()} *@param host-URL host,例如,{@link java.net.URL#getHost()}。 *@param path-URL path,例如,{@link java.net.URL#getPath()}。 *@param query-URL query(参数按排序顺序排列,请参见AWS规范),例如,{@link java.net.URL#getQuery()}。 *@param headers-HTTP请求头映射。此映射将通过此方法添加条目。最初填充为 *要包含在签名中的头。通常是强制的“主机”头。例如,{@link java.net.HttpURLConnection#getRequestProperties()}。 *@param body-二进制请求正文,用于POST等请求。 *@param isoDateTime-ISO8601基本格式的请求的时间和日期,请参见上面的注释。 *@param awsIdentity-AWS标识,例如,“AKIAJTOUYS27JPVRDUYQ” *@param awsSecret-AWS密钥,例如,“I8Q2hY819e+7KzBnkXj66n1GI9piV+0p3dHglAzQ” *@param awsRegion-AWS区域,例如“us-east-1” *@param awsService-AWS服务,例如“route53” */ 公共静态void CalculateAuthorizationHeader( 字符串方法、字符串宿主、字符串路径、字符串查询、映射头、, 字节[]正文, 字符串isoDateTime, 字符串awsIdentity、字符串awsSecret、字符串awsRegion、字符串awsService ) { 试一试{ 字符串bodySha256=hex(sha256(body)); String isoJustDate=isoDateTime.substring(0,8);//剪切字符串的日期部分,如'20150830T123600Z'; headers.put(“主机”,主机); headers.put(“X-Amz-Content-Sha256”,bodySha256); headers.put(“X-Amz-Date”,isoDateTime); // (1) https://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html List canonicalRequestLines=new ArrayList(); canonicalRequestLines.add(方法); canonicalRequestLines.add(路径); canonicalRequestLines.add(查询); List hashedHeaders=new ArrayList(); 对于(条目e:headers.entrySet()){ add(e.getKey().toLowerCase()); canonicalRequestLines.add(e.getKey().toLowerCase()+“:”+规范化空间(e.getValue().toString()); } canonicalRequestLines.add(null);//在标题后需要新行 String signedHeaders=hashedHeaders.stream().collect(collector.joining(“;”); canonicalRequestLines.add(signedHeaders); canonicalRequestLines.add(bodySha256); 字符串canonicalRequestBody=canonicalRequestLines.stream().map(line->line==null?”:line.collect(收集器.加入(“\n”)); 字符串canonicalRequestHash=hex(sha256(canonicalRequestBody.getBytes(StandardCharsets.UTF_8)); // (2) https://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html List strignToSignLines=new ArrayList(); strignToSignLines.添加(“AWS4-HMAC-SHA256”); strignToSignLines.add(isoDateTime); String credentialScope=isoJustDate+“/”+awsRegion+“/”+awsService+“/aws4_请求”; 添加(凭证范围); 添加(canonicalRequestHash); 字符串stringToSign=StringToSignlines.stream().collect(收集器.joining(“\n”)); // (3) https://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html byte[]kDate=hmac(((“AWS4”+awsSecret).getBytes(StandardCharsets.UTF_8),isoJustDate);