簡體   English   中英

嘗試使用cloudfront和privateKey訪問S3(靜態網站托管)中存儲的私有內容時,獲取HTTP / 1.1 403禁止

[英]get HTTP/1.1 403 Forbidden when trying to access private content stored in S3(static web hosting) using cloudfront and privateKey

我收到來自Java應用程序的AWS CloudFront的以下響應,該應用程序試圖使用簽名的cookie訪問私有內容(網頁)。

HTTP / 1.1 403禁止[內容類型:application / xml,傳輸編碼:分塊,連接:keep-alive,日期:Fri,23 Aug 2019 12:47:53 GMT,服務器:AmazonS3,X-Cache:來自cloudfront,通過:1.1 1b964435 *********** d975cdd ***。cloudfront.net(CloudFront),X-Amz-Cf-Pop:MXP64-C1,X-Amz-Cf-Id:6Waw **** _ ukbfaev1nrJZZYBl ********** t66R9ctZ ***** A ==] org.apache.http.conn.BasicManagedEntity@5fdba6f9

我嘗試了以下步驟:

  1. 我已將S3配置為“靜態網站托管”
  2. 將存儲桶策略設置為:
{
    "Version": "2012-10-17",
    "Statement": [
          {
            "Sid": "2",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity E1J***SIQ****"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::my-xxxxx-s3-bucket/*"
        }
    ]
}
  1. 存儲桶的CORS配置為:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <AllowedMethod>HEAD</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
  1. 使用以下方法創建CloudFront分配:

    • 原始設置->原始域名:my-s3-bucket-name
    • 原始設置->限制存儲區訪問:是
    • 限制查看者訪問(使用簽名的URL或簽名的Cookie):是。
    • 受信任的簽名者:自我(選中)。
    • 將其余屬性保留為默認值。
  2. 在(CloudFront密鑰對)下創建了安全憑證,並下載了私鑰。 使用以下命令將.pem文件轉換為.der。

openssl pkcs8 -topk8 -nocrypt -in origin.pem -inform PEM -out new.der -outform DER 
  1. 創建了一個具有以下依賴項的Maven項目:
<dependencies>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk</artifactId>
    <version>1.11.327</version>
  </dependency>

    <!-- https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk15on -->
<dependency>
    <groupId>org.bouncycastle</groupId>
    <artifactId>bcprov-jdk15on</artifactId>
    <version>1.62</version>
</dependency>

<!-- https://mvnrepository.com/artifact/net.java.dev.jets3t/jets3t -->
<dependency>
    <groupId>net.java.dev.jets3t</groupId>
    <artifactId>jets3t</artifactId>
    <version>0.9.4</version>
</dependency>
  1. 代碼如下,嘗試使用簽名的cookie訪問“ index.html”文件(在S3中保存在根目錄中):
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.spec.InvalidKeySpecException;
import java.text.ParseException;
import java.util.Date;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.jets3t.service.CloudFrontServiceException;

import com.amazonaws.services.cloudfront.CloudFrontCookieSigner;
import com.amazonaws.services.cloudfront.CloudFrontCookieSigner.CookiesForCustomPolicy;
import com.amazonaws.services.cloudfront.util.SignerUtils;
import com.amazonaws.services.cloudfront.util.SignerUtils.Protocol;
import com.amazonaws.util.DateUtils;

public class SignedCookies {

    public static void withCustom() throws InvalidKeySpecException, IOException{

        Protocol protocol = Protocol.http;
        String resourcePath = "index.html";
        String distributionDomain = "***ju***lu***.cloudfront.net";
        String privateKeyFilePath = "my-path/pk-APKA####K3WH####7U##.der";
        File privateKeyFile = new File(privateKeyFilePath);
        String s3ObjectKey = "index.html";
        String keyPairId = "APKA####K3WH####7U##";


         Date activeFrom = DateUtils.parseISO8601Date("2018-11-14T22:20:00.000Z");
         Date expiresOn = DateUtils.parseISO8601Date("2020-11-14T22:20:00.000Z");
         String ipRange = null;

         CookiesForCustomPolicy cookies = CloudFrontCookieSigner.getCookiesForCustomPolicy(
                      protocol, distributionDomain, privateKeyFile, s3ObjectKey,
                      keyPairId, expiresOn, activeFrom, ipRange);


         @SuppressWarnings({ "resource", "deprecation" })
        HttpClient client = new DefaultHttpClient();
         HttpGet httpGet = new HttpGet(
                      SignerUtils.generateResourcePath(protocol, distributionDomain,
                      resourcePath));

         httpGet.addHeader("Cookie", "Secure");
         httpGet.addHeader("Cookie", cookies.getPolicy().getKey() + "=" +
             cookies.getPolicy().getValue());
         httpGet.addHeader("Cookie", cookies.getSignature().getKey() + "=" +
             cookies.getSignature().getValue());
         httpGet.addHeader("Cookie", cookies.getKeyPairId().getKey() + "=" +
             cookies.getKeyPairId().getValue());


         HttpResponse response = client.execute(httpGet);

         System.out.println(response.toString());

    }

    public static void main(String[] args) throws FileNotFoundException, IOException, CloudFrontServiceException, ParseException, InvalidKeySpecException {
        withCustom();
    }

}

  1. 而且我已經收到403的回復。

如何解決此問題?

請先閱讀我在第一篇文章中的最后評論。 這部分與上一篇文章有​​關。 這是我用來用signUrlCanned簽名URL並獲取內容的代碼示例,但是當我嘗試使用buildPolicyForSignedUrl時,訪問被拒絕錯誤。

@JamesDean:感謝您的評論。 在上面的例子中。 我從下拉列表中選擇“原始域名”(作為s3存儲桶),並使用OAI(其中我將S3配置為靜態網站),這是我的第一個錯誤。 無論如何,我通過提供自定義來源名稱(靜態網站端點網址)解決了此問題。 然后在未啟用“使用簽名的URL或簽名的Cookie”的情況下進行了測試,並且可以正常工作。 但是如果啟用“使用簽名的URL或簽名的cookie”並嘗試使用簽名的URL或簽名的cookie,則會收到403錯誤,但我無法解決。 如果您仍然可以幫助我,我將在下面提供代碼示例。

使用以下代碼,我可以獲得正確的簽名URL,並且可以訪問內容:

byte[] derPrivateKey = EncryptionUtil.convertRsaPemToDer(new FileInputStream(privateKeyFilePath));
//      Generate a "canned" signed URL to allow access to a specific distribution and object

        String signedUrlCanned = CloudFrontService.signUrlCanned(
            "https://" + distributionDomain + "/" + s3ObjectKey, // Resource URL or Path
            keyPairId,     // Certificate identifier, an active trusted signer for the distribution
            derPrivateKey, // DER Private key data
            ServiceUtils.parseIso8601Date("2020-08-30T22:20:00.000Z") // DateLessThan
            );
        System.out.println(signedUrlCanned);

另一方面,當我嘗試使用針對相同s3內容(根目錄中的index.html)的自定義策略訪問內容時,訪問被拒絕:

String policyResourcePath = distributionDomain + "/*" ;
//      Convert an RSA PEM private key file to DER bytes

        byte[] derPrivateKey = EncryptionUtil.convertRsaPemToDer(new FileInputStream(privateKeyFilePath));

        String policy = CloudFrontService.buildPolicyForSignedUrl(
                policyResourcePath, // Resource path (optional, may include '*' and '?' wildcards)
                ServiceUtils.parseIso8601Date("2020-11-14T22:20:00.000Z"), // DateLessThan
                "0.0.0.0/0", // CIDR IP address restriction (optional, 0.0.0.0/0 means everyone)
                ServiceUtils.parseIso8601Date("2017-10-16T06:31:56.000Z")  // DateGreaterThan (optional)
                );

        String signedUrl = CloudFrontService.signUrl(
                "https://" + distributionDomain + "/" + s3ObjectKey, // Resource URL or Path
                keyPairId,     // Certificate identifier, an active trusted signer for the distribution
                derPrivateKey, // DER Private key data
                policy // Access control policy
                );
            System.out.println(signedUrl);

我收到的回復:


<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>AccessDenied</Code>
    <Message>Access denied</Message>
</Error>

代碼參考: https : //jets3t.s3.amazonaws.com/toolkit/code-samples.html

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM