S3如何通過簽名的URL來完成訪問控制

S3如何通過簽名的URL來完成訪問控制
 
作者:光環雲 尹曉徵

 
S3(Amazon Simple Storage Service)是一種對象存儲服務,提供可擴展性、數據可用性、安全性和性能。S3 可達到 99.999999999%(11 個 9)的持久性。客戶使用 S3 作爲雲原生應用程序的主要存儲;作爲分析的批量存儲庫或“數據湖”;作爲備份和恢復以及災難恢復的目標;並將其與無服務器計算配合使用。
 

現在越來越多的客戶使用S3作爲網站的一個資源存儲方案。在當前對於流量就是金錢而言的雲計算時代,如何能夠更好的使用公有云服務商提供的豐富PaaS服務的同時,如果不讓網絡上爬蟲等工具肆意的盜取網站各種資源就是工程師們需要面對的問題。不過,不用擔心AWS S3的對象簽名機制就提供了一個非常好的選擇。
 

通過S3的對象URL簽名,可以避免將對象直接暴露在公網上,簽名可以控制對象的可訪問時間。
 

閒話不多說,我們來直接上代碼:
 

package com.sinnet.S3;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.Iterator;
import java.util.Map;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.HttpMethod;
import com.amazonaws.SdkClientException;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import com.amazonaws.services.s3.model.S3Object;
public class GeneratePresignedUrlAndUploadObject {
    public static void main(String[] args) throws IOException {
        String clientRegion = "*** Client region ***";
        String bucketName = "*** Bucket name ***";
        String objectKey = "*** Object key ***"; 
        try {
            AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                    .withCredentials(new ProfileCredentialsProvider())
                    .withRegion(clientRegion)
                    .build();
            // Set the pre-signed URL to expire after one hour.
            java.util.Date expiration = new java.util.Date();
            long expTimeMillis = expiration.getTime();
            expTimeMillis += 2 * 60 * 1000;
            expiration.setTime(expTimeMillis);
            java.util.Date DLexpiration = new java.util.Date();
            long downloadExpTimeMillis = DLexpiration.getTime();
            downloadExpTimeMillis += 60 * 1000;
            DLexpiration.setTime(downloadExpTimeMillis);
            // Generate the pre-signed URL.
            System.out.println("Generating pre-signed URL."); 
            GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(bucketName, objectKey)
                    .withMethod(HttpMethod.PUT)
                    .withExpiration(expiration);
            URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
            System.out.println("Upload url=" + url);
            String str = uploadFile(url.toString(),new String[] { "***upload file path***"  });
            System.out.println(str);
            // Check to make sure that the object was uploaded successfully.
            S3Object object = s3Client.getObject(bucketName, objectKey);
            if (object.getKey() != "")
            {
                   System.out.println("Success: Object " + object.getKey() + " created in bucket " + object.getBucketName());
                   GeneratePresignedUrlRequest generatePresignedUrlRequest1 = new GeneratePresignedUrlRequest(bucketName, objectKey)
                        .withMethod(HttpMethod.GET)
                        .withExpiration(DLexpiration);
                URL url1 = s3Client.generatePresignedUrl(generatePresignedUrlRequest1);
                System.out.println("Download url=" + url1);
            }
            else {
                           System.out.println("ERROR: Can not find " + object.getKey() + "in bucket " + object.getBucketName());
                     }
        }
        catch(AmazonServiceException e) {
            // The call was transmitted successfully, but Amazon S3 couldn't process
            // it, so it returned an error response.
            e.printStackTrace();
        }
        catch(SdkClientException e) {
            // Amazon S3 couldn't be contacted for a response, or the client 
            // couldn't parse the response from Amazon S3.
            e.printStackTrace();
        }
    }
     /**
      *
      * @param actionUrl:上傳的路徑
      * @param uploadFilePaths:需要上傳的文件路徑,數組
      * @return
      */
     @SuppressWarnings("finally")
     public static String uploadFile(String actionUrl, String[] uploadFilePaths) {
      String boundary = "*****";
      DataOutputStream ds = null;
      InputStream inputStream = null;
      InputStreamReader inputStreamReader = null;
      BufferedReader reader = null; 
      StringBuffer resultBuffer = new StringBuffer();
      String tempLine = null;
      try {
       // 統一資源
       URL url = new URL(actionUrl);
       // 連接類的父類,抽象類
       URLConnection urlConnection = url.openConnection();
       // http的連接類
       HttpURLConnection httpURLConnection = (HttpURLConnection) urlConnection;
       // 設置是否從httpUrlConnection讀入,默認情況下是true;
       httpURLConnection.setDoInput(true);
       // 設置是否向httpUrlConnection輸出
       httpURLConnection.setDoOutput(true);
       // Post 請求不能使用緩存
       httpURLConnection.setUseCaches(false);
       // 設定請求的方法,默認是GET
       httpURLConnection.setRequestMethod("PUT");
       // 設置字符編碼連接參數
       httpURLConnection.setRequestProperty("Connection", "Keep-Alive");
       // 設置字符編碼
       httpURLConnection.setRequestProperty("Charset", "UTF-8");
       // 設置請求內容類型
       httpURLConnection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
       // 設置DataOutputStream
       ds = new DataOutputStream(httpURLConnection.getOutputStream());
       for (int i = 0; i < uploadFilePaths.length; i++) {
        String uploadFile = uploadFilePaths[i];
        String filename = uploadFile.substring(uploadFile.lastIndexOf("//") + 1);
        FileInputStream fStream = new FileInputStream(uploadFile);
        int bufferSize = 1024;
        byte[] buffer = new byte[bufferSize];
        int length = -1;
        while ((length = fStream.read(buffer)) != -1) {
         ds.write(buffer, 0, length);
        }
        /* close streams */
        fStream.close();
       }
       /* close streams */
       ds.flush();
       if (httpURLConnection.getResponseCode() >= 300) {
        throw new Exception(
          "HTTP Request is not success, Response code is " + httpURLConnection.getResponseCode() + "\n"
          + "HTTP body=" + httpURLConnection.getContent());
       }
       if (httpURLConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
        inputStream = httpURLConnection.getInputStream();
        inputStreamReader = new InputStreamReader(inputStream);
        reader = new BufferedReader(inputStreamReader);
        tempLine = null;
        resultBuffer = new StringBuffer();
        while ((tempLine = reader.readLine()) != null) {
         resultBuffer.append(tempLine);
         resultBuffer.append("\n");
        }
       }
      } catch (Exception e) {
       // TODO Auto-generated catch block
       e.printStackTrace();
      } finally {
       if (ds != null) {
        try {
         ds.close();
        } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
       }
       if (reader != null) {
        try {
         reader.close();
        } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
       }
       if (inputStreamReader != null) {
        try {
         inputStreamReader.close();
        } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
       }
       if (inputStream != null) {
        try {
         inputStream.close();
        } catch (IOException e) {
         // TODO Auto-generated catch block
         e.printStackTrace();
        }
       }
       return resultBuffer.toString();
      }
     }
}

 
關於光環雲:
 
光環雲是AWS服務在華推廣機構,是一家由光環新網組建的獨立業務部門公司。它開發、組建、運營一個全國的雲生態系統,以促進、支持AWS服務廣大客戶,包括開發者、初創公司、互聯網企業、社會與政府機構,以及ICT服務商。
 

關於光環雲社羣:
 
光環雲社羣是光環雲生態夥伴計劃,致力於與推廣者實現普惠科技,以社會化營銷驅動雲端生態。加入光環雲社羣后將獲得AWS產品推廣返現、AWS認證優惠、技術文章獲取等特權,並得到光環雲多項權益賦能支持。
 
微信搜索“光環雲社羣”或掃描下方二維碼,獲取更多資訊。
 
S3如何通過簽名的URL來完成訪問控制
 
最終解釋權歸光環雲數據有限公司!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章