AWS APIGW Signature使用示例代码

1. 引入SDK依赖包

        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.12</version>
        </dependency>
        <!-- AWS SDK for Java Signing -->
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>signer</artifactId>
            <version>2.17.35</version>
        </dependency>

2. 调用请求Demo

import org.apache.http.HttpHeaders;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpRequestRetryHandler;
import org.apache.http.impl.client.HttpClientBuilder;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.signer.Aws4Signer;
import software.amazon.awssdk.auth.signer.params.Aws4SignerParams;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.http.SdkHttpFullRequest;
import software.amazon.awssdk.http.SdkHttpMethod;
import software.amazon.awssdk.regions.Region;

import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.time.Instant;

public class Aws4SignerDemo {
    private static final String HOST = "https://your-apigw-domain";
    private static final String REGION = "cn-northwest-1";
    private static final String AK = "BKBA4WFLST4Cd5O7WE3Pc";
    private static final String SK = "AmslC6UAqe0LS0J7/773vFHl6DSt9nfV96o5eBxD";

    public static void main(String[] args) throws Exception {
        String path = "/v1/person/create";
        URI uri = URI.create(HOST + path);
        String requestBody = "{\"name\": \"111\",\"age\": \"22\"}"
        SdkHttpFullRequest signedRequest = getSignature(uri, requestBody);

        String response = doPost(uri, requestBody, signedRequest);

        System.out.println(response);
    }

    private static SdkHttpFullRequest getSignature(URI uri, String requestBody){
        Aws4Signer signer = Aws4Signer.create();
        SdkHttpFullRequest.Builder requestBuilder = SdkHttpFullRequest.builder()
                .method(SdkHttpMethod.POST)
                .uri(uri);
        requestBuilder.putHeader("Host", uri.getHost());
        requestBuilder.putHeader("X-Amz-Date", Instant.now().toString());
        byte[] payload = requestBody.getBytes();
        requestBuilder.contentStreamProvider(() -> SdkBytes.fromByteArray(payload).asInputStream());

        Aws4SignerParams signingParams = Aws4SignerParams.builder()
                .awsCredentials(AwsBasicCredentials.create(AK,SK))
                .signingName("execute-api")
                .signingRegion(Region.of(REGION))
                .build();
        return signer.sign(requestBuilder.build(), signingParams);
    }

    private static String doPost(URI uri,String requestBody, SdkHttpFullRequest signedRequest) throws Exception {
        HttpClient httpClient = HttpClientBuilder.create()
                .setRetryHandler(new DefaultHttpRequestRetryHandler(3, false))
                .build();
        HttpPost request = new HttpPost(uri);
        request.setHeader(HttpHeaders.HOST, uri.getHost());
        request.setHeader("X-Amz-Date", signedRequest.firstMatchingHeader("X-Amz-Date").orElse(null));
        request.setHeader("Authorization",signedRequest.firstMatchingHeader("Authorization").orElse(null));
        request.setHeader("Content-Type", "application/json");
        request.setEntity(new StringEntity(requestBody, StandardCharsets.UTF_8));
        String result = null;
        HttpResponse response = httpClient.execute(request);
        byte[] responseBody = response.getEntity() != null ?
                SdkBytes.fromInputStream(response.getEntity().getContent()).asByteArray() : null;
        if (responseBody != null) {
            result = new String(responseBody);
        }
        return result;
    }

}

3. APIGW需要配置对应的API使用Signature鉴权

---
swagger: "2.0"
info:
  description: "test"
host: "your-apigw-domain"
basePath: "/v3"
schemes:
- "https"
paths:
  /person/create:
    post:
      produces:
      - "application/json"
      security:
      - sigv4: []
      x-amazon-apigateway-request-validator: "Validate body"
securityDefinitions:
  sigv4:
    type: "apiKey"
    name: "Authorization"
    in: "header"
    x-amazon-apigateway-authtype: "awsSigv4"
x-amazon-apigateway-policy:
  Version: "2012-10-17"
  Statement:
  - Sid: "abcv1"
    Effect: "Allow"
    Principal:
      AWS: "arn:aws-cn:iam::172238194437:user/username"
    Action: "execute-api:Invoke"
    Resource:
    - "arn:aws-cn:execute-api:cn-northwest-1:172238194437:11qx76lfea/v1/POST/person/create"
    Condition:
      IpAddress:
        aws:SourceIp:
        - "0.0.0.0/0"
x-amazon-apigateway-request-validators:
  Validate body:
    validateRequestParameters: false
    validateRequestBody: true

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
使用AWS Signature进行身份验证需要遵循以下步骤: 1. 创建规范请求(Canonical Request):从HTTP请求中提取所有必需的信息(如HTTP方法、请求路径、查询参数、头部信息和请求体),并按照一定的格式组织这些信息。 2. 创建待签名字符串(String to Sign):将规范请求和其他必需的信息(如时间戳、区域和服务名称)组织成待签名字符串。 3. 计算签名:使用AWS提供的凭证信息,签名密钥和待签名字符串计算签名。 4. 添加签名到请求中:将签名加入到请求头中以进行身份验证。 下面是一个简单的示例,展示如何使用AWS Signature Version 4进行身份验证: 假设我们要向AWS的S3服务发送一个PUT请求,上传一个名为“example.txt”的文件到一个名为“my-bucket”的存储桶中。我们需要使用AWS Signature Version 4进行身份验证: 1. 创建规范请求: ``` PUT /my-bucket/example.txt uploadId=1234567890&partNumber=1 host:s3.amazonaws.com x-amz-date:20220101T000000Z x-amz-content-sha256:hash-of-request-payload ``` 2. 创建待签名字符串: ``` AWS4-HMAC-SHA256 20220101T000000Z 20220101/us-east-1/s3/aws4_request hash-of-canonical-request ``` 3. 计算签名: 使用AWS提供的凭证信息,签名密钥和待签名字符串计算签名。 4. 添加签名到请求中: 将签名加入到请求头中以进行身份验证。 ``` Authorization: AWS4-HMAC-SHA256 Credential=access-key-id/20220101/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=signature ``` 在以上示例中,access-key-id和secret-access-key是AWS提供的凭证信息。我们使用这些信息,结合请求的其他信息,计算签名,并将签名添加到请求头中,以便服务器进行身份验证。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值