生成预签名URL保证S3资源安全访问

为了节约成本,可将静态资源存储在AWS S3上,而不是存储在EC2上。但S3资源默认是私有的,只有Owner登录后才能访问,如果将资源改为Public的,这又不安全,那怎么办呢?可以使用AWS SDK生成预签名的URL,限定用户在有限的时间内可访问。

Set up the AWS SDK for Java

  1. Download the SDK from http://sdk-for-java.amazonwebservices.com/latest/aws-java-sdk.zip.

  2. After downloading the SDK, extract the contents into a local directory.

To use the SDK, add the full path to the lib and third-party directories to the dependencies in your build file, and add them to your java CLASSPATH to run your code.

Using the SDK with Apache Maven

Add a <dependencyManagement> section to your application’s pom.xml file:

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.amazonaws</groupId>
      <artifactId>aws-java-sdk-bom</artifactId>
      <version>1.11.41</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

You can now select individual modules from the SDK that you use in your application

<dependencies>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-s3</artifactId>
  </dependency>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk-dynamodb</artifactId>
  </dependency>
</dependencies>

If you would like to pull in the entire SDK as a dependency, don’t use the BOM method, but simply declare it in your pom.xml like this:

<dependencies>
  <dependency>
    <groupId>com.amazonaws</groupId>
    <artifactId>aws-java-sdk</artifactId>
    <version>1.11.41</version>
  </dependency>
</dependencies>

Set up AWS Credentials for Development

To connect to any of the supported services with the AWS SDK for Java, you must provide AWS credentials.

Set credentials in the AWS credentials profile file on your local system, located at:

  • ~/.aws/credentials on Linux, OS X, or Unix
  • C:\Users\USERNAME\.aws\credentials on Windows

This file should contain lines in the following format:

[default]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key

Generate a Pre-signed Object URL using AWS SDK for Java

All objects by default are private. Only the object owner has permission to access these objects. However, the object owner can optionally share objects with others by creating a pre-signed URL, using their own security credentials, to grant time-limited permission to download the objects.

When you create a pre-signed URL for your object, you must provide your security credentials, specify a bucket name, an object key, specify the HTTP method (GET to download the object) and expiration date and time. The pre-signed URLs are valid only for the specified duration.

import java.io.IOException;
import java.net.URL;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.HttpMethod;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;

public class GeneratePreSignedUrl {
	private static String bucketName = "*** Provide a bucket name ***"; 
	private static String objectKey  =  "*** Provide an object key ***";

	public static void main(String[] args) throws IOException {
		AmazonS3 s3client = new AmazonS3Client(new ProfileCredentialsProvider());

		try {
			System.out.println("Generating pre-signed URL.");
			java.util.Date expiration = new java.util.Date();
			long milliSeconds = expiration.getTime();
			milliSeconds += 1000 * 60 * 60; // Add 1 hour.
			expiration.setTime(milliSeconds);

			GeneratePresignedUrlRequest generatePresignedUrlRequest = 
				    new GeneratePresignedUrlRequest(bucketName, objectKey);
			generatePresignedUrlRequest.setMethod(HttpMethod.GET); 
			generatePresignedUrlRequest.setExpiration(expiration);

			URL url = s3client.generatePresignedUrl(generatePresignedUrlRequest); 

			System.out.println("Pre-Signed URL = " + url.toString());
		} catch (AmazonServiceException exception) {
			System.out.println("Caught an AmazonServiceException, " +
					"which means your request made it " +
					"to Amazon S3, but was rejected with an error response " +
			"for some reason.");
			System.out.println("Error Message: " + exception.getMessage());
			System.out.println("HTTP  Code: "    + exception.getStatusCode());
			System.out.println("AWS Error Code:" + exception.getErrorCode());
			System.out.println("Error Type:    " + exception.getErrorType());
			System.out.println("Request ID:    " + exception.getRequestId());
		} catch (AmazonClientException ace) {
			System.out.println("Caught an AmazonClientException, " +
					"which means the client encountered " +
					"an internal error while trying to communicate" +
					" with S3, " +
			"such as not being able to access the network.");
			System.out.println("Error Message: " + ace.getMessage());
		}
	}
}

Amazon Simple Storage Service Documentation

Working with Amazon S3 Objects

Using the SDK

Programming Examples

猜你喜欢

转载自billben.iteye.com/blog/2329323