AWS-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认证优惠、技术文章获取等特权,并得到光环云多项权益赋能支持。
微信搜索“光环云社群”或扫描下方二维码,获取更多资讯

AWS-S3如何通过签名的URL来完成访问控制_第1张图片

你可能感兴趣的:(AWS-S3如何通过签名的URL来完成访问控制)