java - AWS Java SDK2 中 CloudFrontUrlSigner 的替代品

标签 java aws-sdk amazon-cloudfront

我使用 Java 11。由于 AWS Java SDK2 支持 Java 11,我使用 SDK2。如何为 s3 key 创建云前端 url。我能够获得许多 SDK 1.x 版本的示例,但不能获得 SDK2 的示例。 1.x 中 url 是这样生成的

CloudFrontUrlSigner.getSignedURLWithCannedPolicy(url, keyPairId, privateKey, expires)

SDK 2.x 版本是否有任何替代方法或替代方法

最佳答案

我认为它尚未实现。与此同时,从旧版本中提取代码来做同样的事情相当容易。

这是来自 https://github.com/dashpradeep99/aws-sdk-java-code/blob/master/aws-java-sdk-cloudfront/src/main/java/com/amazonaws/services/cloudfront/util/SignerUtils.java

https://github.com/dashpradeep99/aws-sdk-java-code/blob/master/aws-java-sdk-cloudfront/src/main/java/com/amazonaws/services/cloudfront/CloudFrontUrlSigner.java

import software.amazon.awssdk.core.exception.SdkException;

import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.util.Date;

import static java.util.concurrent.TimeUnit.MILLISECONDS;

public class AwsUtils {

  private static final SecureRandom srand = new SecureRandom();

  /**
   * Generates a signed url that expires after given date.
   * @param resourceUrlOrPath The url.
   * @param keyPairId The keypair id used to sign.
   * @param privateKey The private key.
   * @param dateLessThan The expire date/time.
   * @return A valid cloudwatch url.
   * @throws SdkException If any errors occur during the signing process.
   */
  public static String getSignedUrlWithCannedPolicy(String resourceUrlOrPath,
                                                    String keyPairId,
                                                    PrivateKey privateKey,
                                                    Date dateLessThan) throws SdkException {
    try {
      String cannedPolicy = buildCannedPolicy(resourceUrlOrPath, dateLessThan);
      byte[] signatureBytes = signWithSha1Rsa(cannedPolicy.getBytes(StandardCharsets.UTF_8), privateKey);
      String urlSafeSignature = makeBytesUrlSafe(signatureBytes);
      return resourceUrlOrPath
          + (resourceUrlOrPath.indexOf('?') >= 0 ? "&" : "?")
          + "Expires=" + MILLISECONDS.toSeconds(dateLessThan.getTime())
          + "&Signature=" + urlSafeSignature
          + "&Key-Pair-Id=" + keyPairId;
    } catch (InvalidKeyException e) {
      throw SdkException.create("Couldn't sign url", e);
    }
  }

  /**
   * Returns a "canned" policy for the given parameters.
   * For more information, see <a href=
   * "http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-urls-overview.html"
   * >Overview of Signed URLs</a>.
   * @param resourceUrlOrPath The resource to grant access.
   * @param dateLessThan The expiration time.
   * @return the aws policy as a string.
   */
  public static String buildCannedPolicy(String resourceUrlOrPath,
                                         Date dateLessThan) {
    return "{\"Statement\":[{\"Resource\":\""
        + resourceUrlOrPath
        + "\",\"Condition\":{\"DateLessThan\":{\"AWS:EpochTime\":"
        + MILLISECONDS.toSeconds(dateLessThan.getTime())
        + "}}}]}";
  }

  /**
   * Signs the data given with the private key given, using the SHA1withRSA
   * algorithm provided by bouncy castle.
   * @param dataToSign The data to sign.
   * @param privateKey The private key.
   * @return A signature.
   * @throws InvalidKeyException if an invalid key was provided.
   */
  public static byte[] signWithSha1Rsa(byte[] dataToSign,
                                       PrivateKey privateKey) throws InvalidKeyException {
    Signature signature;
    try {
      signature = Signature.getInstance("SHA1withRSA");
      signature.initSign(privateKey, srand);
      signature.update(dataToSign);
      return signature.sign();
    } catch (NoSuchAlgorithmException | SignatureException e) {
      throw new IllegalStateException(e);
    }
  }

  /**
   * Converts the given data to be safe for use in signed URLs for a private
   * distribution by using specialized Base64 encoding.
   * @param bytes The bytes
   */
  public static String makeBytesUrlSafe(byte[] bytes) {
    byte[] encoded = java.util.Base64.getEncoder().encode(bytes);

    for (int i = 0; i < encoded.length; i++) {
      switch (encoded[i]) {
        case '+':
          encoded[i] = '-';
          continue;
        case '=':
          encoded[i] = '_';
          continue;
        case '/':
          encoded[i] = '~';
          continue;
        default:
          continue;
      }
    }
    return new String(encoded, StandardCharsets.UTF_8);
  }
}

关于java - AWS Java SDK2 中 CloudFrontUrlSigner 的替代品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56472243/

相关文章:

java - 应用程序部署后无法访问服务器

java - java.lang.reflect.Field 实例在单个类加载器中是唯一的吗?

javascript - AWS Lambda 调用函数 (js sdk) : timeout resets to default

amazon-web-services - Cloudfront URL 与 AWS 上的 S3 URL

java - Android AudioRecord 读取总是返回 -3 (ERROR_INVALID_OPERATION)

java - 如何创建没有键的 JSONObject?

java - 如何修复导致 ExpiredTokenException 的 AWS Java SDK DynamoDB 调用?

amazon-web-services - 您如何通过 AWS API 确定 Redshift 集群的 ARN?

amazon-cloudfront - 如何在查看者响应的Cloudfront事件中更改状态代码?

url-rewriting - 用 lambda@edge 重写 cloudfront 源主机,如何?