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认证优惠、技术文章获取等特权,并得到光环云多项权益赋能支持。

微信搜索“光环云社群”或扫描下方二维码,获取更多资讯。
在这里插入图片描述
最终解释权归光环云数据有限公司!

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值