Package org.jets3t.service

Source Code of org.jets3t.service.TestAWSRequestSignatureVersion4

package org.jets3t.service;

import java.io.InputStream;
import java.util.Properties;

import junit.framework.TestCase;

import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.jets3t.service.impl.rest.httpclient.RestS3Service;
import org.jets3t.service.model.S3Object;
import org.jets3t.service.security.AWSCredentials;
import org.jets3t.service.security.ProviderCredentials;
import org.jets3t.service.utils.ServiceUtils;
import org.jets3t.service.utils.SignatureUtils;
import org.junit.Test;


/**
* {@link "http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html"}
*/
public class TestAWSRequestSignatureVersion4 extends TestCase {
    protected String TEST_PROPERTIES_FILENAME = "test.properties";
    protected Properties testProperties = null;
    protected ProviderCredentials testCredentials = null;

    String awsAccessKey = "AKIAIOSFODNN7EXAMPLE";
    String awsSecretAccessKey = "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY";
    String timestampISO8601 = "20130524T000000Z";
    String bucketName = "examplebucket";
    String region = "us-east-1";
    String service = "s3";
    String requestSignatureVersion = "AWS4-HMAC-SHA256";

    public TestAWSRequestSignatureVersion4() throws Exception {
        // Load test properties
        InputStream propertiesIS =
            ClassLoader.getSystemResourceAsStream(TEST_PROPERTIES_FILENAME);
        if (propertiesIS == null) {
            throw new Exception(
                "Unable to load test properties file from classpath: "
                + TEST_PROPERTIES_FILENAME);
        }
        this.testProperties = new Properties();
        this.testProperties.load(propertiesIS);

        this.testCredentials = new AWSCredentials(
            testProperties.getProperty("aws.accesskey"),
            testProperties.getProperty("aws.secretkey"));
    }

    @Test
    public void testS3ApiReferenceExampleGetObject() {
        HttpGet httpGet = new HttpGet("http://examplebucket.s3.amazonaws.com/test.txt");
        httpGet.setHeader("Host", "examplebucket.s3.amazonaws.com");
        // NOTE: Date header missed in example test case
        httpGet.setHeader("Range", "bytes=0-9");
        httpGet.setHeader("x-amz-content-sha256",
            "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855");
        httpGet.setHeader("x-amz-date", this.timestampISO8601);

        // Default empty payload hash
        String requestPayloadHexSHA256Hash =
            "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";

        // Canonical request string
        String expected =
            "GET\n" +
            "/test.txt\n" +
            "\n" +
            "host:examplebucket.s3.amazonaws.com\n" +
            "range:bytes=0-9\n" +
            "x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" +
            "x-amz-date:20130524T000000Z\n" +
            "\n" +
            "host;range;x-amz-content-sha256;x-amz-date\n"+
            "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
        String canonicalRequestString = SignatureUtils.awsV4BuildCanonicalRequestString(
            httpGet, requestPayloadHexSHA256Hash);
        assertEquals(expected, canonicalRequestString);

        // String to sign
        expected =
            "AWS4-HMAC-SHA256\n" +
            "20130524T000000Z\n" +
            "20130524/us-east-1/s3/aws4_request\n" +
            "7344ae5b7ee6c3e7e6b0fe0640412a37625d1fbfff95c48bbb2dc43964946972";
        String stringToSign = SignatureUtils.awsV4BuildStringToSign(
            requestSignatureVersion, canonicalRequestString,
            this.timestampISO8601, this.region);
        assertEquals(expected, stringToSign);

        // Signature
        byte[] signingKey = SignatureUtils.awsV4BuildSigningKey(
            this.awsSecretAccessKey, this.timestampISO8601,
            this.region);
        String signature = ServiceUtils.toHex(
            ServiceUtils.hmacSHA256(
                signingKey, ServiceUtils.stringToBytes(stringToSign)));
        expected = "f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41";
        assertEquals(expected, signature);

        // Authorization header
        String authorizationHeaderValue =
            SignatureUtils.awsV4BuildAuthorizationHeaderValue(
                this.awsAccessKey, signature, this.requestSignatureVersion,
                canonicalRequestString, this.timestampISO8601, this.region);
        expected = "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;range;x-amz-content-sha256;x-amz-date,Signature=f0e8bdb87c964420e857bd35b5d6ed310bd44f0170aba48dd91039c6036bdb41";
        assertEquals(expected, authorizationHeaderValue);

        // The whole request
        SignatureUtils.awsV4SignRequestAuthorizationHeader(
            this.requestSignatureVersion, httpGet,
            new AWSCredentials(this.awsAccessKey, this.awsSecretAccessKey),
            requestPayloadHexSHA256Hash, this.region);
        assertEquals(expected, httpGet.getFirstHeader("Authorization").getValue());
    }

    @Test
    public void testS3ApiReferenceExamplePutObject() {
        HttpPut httpPut = new HttpPut("http://examplebucket.s3.amazonaws.com/test$file.text");
        httpPut.setHeader("Host", "examplebucket.s3.amazonaws.com");
        httpPut.setHeader("Date", "Fri, 24 May 2013 00:00:00 GMT");
        httpPut.setHeader("x-amz-date", this.timestampISO8601);
        httpPut.setHeader("x-amz-storage-class", "REDUCED_REDUNDANCY");

        String payload = "Welcome to Amazon S3.";
        httpPut.setEntity(new StringEntity(
            payload, ContentType.create("text/plain", Constants.DEFAULT_ENCODING)));

        String requestPayloadHexSHA256Hash = ServiceUtils.toHex(
            ServiceUtils.hash(payload, "SHA-256"));
        httpPut.setHeader("x-amz-content-sha256", requestPayloadHexSHA256Hash);

        // Canonical request string
        String expected =
            "PUT\n" +
            "/test%24file.text\n" +
            "\n" +
            "date:Fri, 24 May 2013 00:00:00 GMT\n" +
            "host:examplebucket.s3.amazonaws.com\n" +
            "x-amz-content-sha256:44ce7dd67c959e0d3524ffac1771dfbba87d2b6b4b4e99e42034a8b803f8b072\n" +
            "x-amz-date:20130524T000000Z\n" +
            "x-amz-storage-class:REDUCED_REDUNDANCY\n" +
            "\n" +
            "date;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class\n" +
            "44ce7dd67c959e0d3524ffac1771dfbba87d2b6b4b4e99e42034a8b803f8b072";
        String canonicalRequestString = SignatureUtils.awsV4BuildCanonicalRequestString(
            httpPut, requestPayloadHexSHA256Hash);
        assertEquals(expected, canonicalRequestString);

        // String to sign
        expected =
            "AWS4-HMAC-SHA256\n" +
            "20130524T000000Z\n" +
            "20130524/us-east-1/s3/aws4_request\n" +
            "9e0e90d9c76de8fa5b200d8c849cd5b8dc7a3be3951ddb7f6a76b4158342019d";
        String stringToSign = SignatureUtils.awsV4BuildStringToSign(
            requestSignatureVersion, canonicalRequestString,
            this.timestampISO8601, this.region);
        assertEquals(expected, stringToSign);

        // Signature
        byte[] signingKey = SignatureUtils.awsV4BuildSigningKey(
            this.awsSecretAccessKey, this.timestampISO8601,
            this.region);
        String signature = ServiceUtils.toHex(
            ServiceUtils.hmacSHA256(
                signingKey, ServiceUtils.stringToBytes(stringToSign)));
        expected = "98ad721746da40c64f1a55b78f14c238d841ea1380cd77a1b5971af0ece108bd";
        assertEquals(expected, signature);

        // Authorization header
        String authorizationHeaderValue =
            SignatureUtils.awsV4BuildAuthorizationHeaderValue(
                this.awsAccessKey, signature, this.requestSignatureVersion,
                canonicalRequestString, this.timestampISO8601, this.region);
        expected = "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=date;host;x-amz-content-sha256;x-amz-date;x-amz-storage-class,Signature=98ad721746da40c64f1a55b78f14c238d841ea1380cd77a1b5971af0ece108bd";
        assertEquals(expected, authorizationHeaderValue);

        // The whole request
        SignatureUtils.awsV4SignRequestAuthorizationHeader(
            this.requestSignatureVersion, httpPut,
            new AWSCredentials(this.awsAccessKey, this.awsSecretAccessKey),
            requestPayloadHexSHA256Hash, this.region);
        assertEquals(expected, httpPut.getFirstHeader("Authorization").getValue());
    }

    @Test
    public void testS3ApiReferenceExampleGetBucketLifecycle() {
        HttpGet httpGet = new HttpGet("http://examplebucket.s3.amazonaws.com?lifecycle");
        httpGet.setHeader("Host", "examplebucket.s3.amazonaws.com");
        // NOTE: Date header missed in example test case
        httpGet.setHeader("x-amz-date", this.timestampISO8601);

        // Empty payload
        String payload = "";
        String requestPayloadHexSHA256Hash = ServiceUtils.toHex(
            ServiceUtils.hash(payload, "SHA-256"));
        httpGet.setHeader("x-amz-content-sha256", requestPayloadHexSHA256Hash);

        // Canonical request string
        String expected =
            "GET\n" +
            "/\n" +
            "lifecycle=\n" +
            "host:examplebucket.s3.amazonaws.com\n" +
            "x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" +
            "x-amz-date:20130524T000000Z\n" +
            "\n" +
            "host;x-amz-content-sha256;x-amz-date\n" +
            "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
        String canonicalRequestString = SignatureUtils.awsV4BuildCanonicalRequestString(
            httpGet, requestPayloadHexSHA256Hash);
        assertEquals(expected, canonicalRequestString);

        // String to sign
        expected =
            "AWS4-HMAC-SHA256\n" +
            "20130524T000000Z\n" +
            "20130524/us-east-1/s3/aws4_request\n" +
            "9766c798316ff2757b517bc739a67f6213b4ab36dd5da2f94eaebf79c77395ca";
        String stringToSign = SignatureUtils.awsV4BuildStringToSign(
            requestSignatureVersion, canonicalRequestString,
            this.timestampISO8601, this.region);
        assertEquals(expected, stringToSign);

        // Signature
        byte[] signingKey = SignatureUtils.awsV4BuildSigningKey(
            this.awsSecretAccessKey, this.timestampISO8601,
            this.region);
        String signature = ServiceUtils.toHex(
            ServiceUtils.hmacSHA256(
                signingKey, ServiceUtils.stringToBytes(stringToSign)));
        expected = "fea454ca298b7da1c68078a5d1bdbfbbe0d65c699e0f91ac7a200a0136783543";
        assertEquals(expected, signature);

        // Authorization header
        String authorizationHeaderValue =
            SignatureUtils.awsV4BuildAuthorizationHeaderValue(
                this.awsAccessKey, signature, this.requestSignatureVersion,
                canonicalRequestString, this.timestampISO8601, this.region);
        expected = "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=fea454ca298b7da1c68078a5d1bdbfbbe0d65c699e0f91ac7a200a0136783543";
        assertEquals(expected, authorizationHeaderValue);

        // The whole request
        SignatureUtils.awsV4SignRequestAuthorizationHeader(
            this.requestSignatureVersion, httpGet,
            new AWSCredentials(this.awsAccessKey, this.awsSecretAccessKey),
            requestPayloadHexSHA256Hash, this.region);
        assertEquals(expected, httpGet.getFirstHeader("Authorization").getValue());
    }

    @Test
    public void testS3ApiReferenceExampleGetBucketListObjects() {
        HttpGet httpGet = new HttpGet("http://examplebucket.s3.amazonaws.com?max-keys=2&prefix=J");
        httpGet.setHeader("Host", "examplebucket.s3.amazonaws.com");
        // NOTE: Date header missed in example test case
        httpGet.setHeader("x-amz-date", this.timestampISO8601);

        // Empty payload
        String payload = "";
        String requestPayloadHexSHA256Hash = ServiceUtils.toHex(
            ServiceUtils.hash(payload, "SHA-256"));
        httpGet.setHeader("x-amz-content-sha256", requestPayloadHexSHA256Hash);

        // Canonical request string
        String expected =
            "GET\n" +
            "/\n" +
            "max-keys=2&prefix=J\n" +
            "host:examplebucket.s3.amazonaws.com\n" +
            "x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\n" +
            "x-amz-date:20130524T000000Z\n" +
            "\n" +
            "host;x-amz-content-sha256;x-amz-date\n" +
            "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
        String canonicalRequestString = SignatureUtils.awsV4BuildCanonicalRequestString(
            httpGet, requestPayloadHexSHA256Hash);
        assertEquals(expected, canonicalRequestString);

        // String to sign
        expected =
            "AWS4-HMAC-SHA256\n" +
            "20130524T000000Z\n" +
            "20130524/us-east-1/s3/aws4_request\n" +
            "df57d21db20da04d7fa30298dd4488ba3a2b47ca3a489c74750e0f1e7df1b9b7";
        String stringToSign = SignatureUtils.awsV4BuildStringToSign(
            requestSignatureVersion, canonicalRequestString,
            this.timestampISO8601, this.region);
        assertEquals(expected, stringToSign);

        // Signature
        byte[] signingKey = SignatureUtils.awsV4BuildSigningKey(
            this.awsSecretAccessKey, this.timestampISO8601,
            this.region);
        String signature = ServiceUtils.toHex(
            ServiceUtils.hmacSHA256(
                signingKey, ServiceUtils.stringToBytes(stringToSign)));
        expected = "34b48302e7b5fa45bde8084f4b7868a86f0a534bc59db6670ed5711ef69dc6f7";
        assertEquals(expected, signature);

        // Authorization header
        String authorizationHeaderValue =
            SignatureUtils.awsV4BuildAuthorizationHeaderValue(
                this.awsAccessKey, signature, this.requestSignatureVersion,
                canonicalRequestString, this.timestampISO8601, this.region);
        expected = "AWS4-HMAC-SHA256 Credential=AKIAIOSFODNN7EXAMPLE/20130524/us-east-1/s3/aws4_request,SignedHeaders=host;x-amz-content-sha256;x-amz-date,Signature=34b48302e7b5fa45bde8084f4b7868a86f0a534bc59db6670ed5711ef69dc6f7";
        assertEquals(expected, authorizationHeaderValue);

        // The whole request
        SignatureUtils.awsV4SignRequestAuthorizationHeader(
            this.requestSignatureVersion, httpGet,
            new AWSCredentials(this.awsAccessKey, this.awsSecretAccessKey),
            requestPayloadHexSHA256Hash, this.region);
        assertEquals(expected, httpGet.getFirstHeader("Authorization").getValue());
    }

    // Very basic test of signed GET request with no payload.
    @Test
    public void testWithServiceListAllBuckets() throws Exception {
        Jets3tProperties properties = new Jets3tProperties();
        properties.setProperty(
            "storage-service.request-signature-version",
            this.requestSignatureVersion);

        RestS3Service service = new RestS3Service(
            this.testCredentials, null, null, properties);

        service.listAllBuckets();
    }

    // Very basic test of signed PUT and DELETE requests with no payload.
    @Test
    public void testWithServiceCreateAndDeleteBucket() throws Exception {
        Jets3tProperties properties = new Jets3tProperties();
        properties.setProperty(
            "storage-service.request-signature-version",
            this.requestSignatureVersion);

        RestS3Service service = new RestS3Service(
            this.testCredentials, null, null, properties);

        String bucketName =
            "test-" + testCredentials.getAccessKey().toLowerCase()
            + "-testwithservicecreatebucket-"
            + System.currentTimeMillis();
        service.createBucket(bucketName);
        service.deleteBucket(bucketName);
    }

    // Test signed PUT requests (with payloads) and DELETE requests for bucket in "eu-central-1"
    // using service that is *not* configured to use AWS4-HMAC-SHA256 signatures by default.
    @Test
    public void testWithServiceCreateAndDeleteBucketAndCreateGetAndDeleteObject() throws Exception {
        RestS3Service service = new RestS3Service(this.testCredentials);

        String bucketName =
            "test-" + testCredentials.getAccessKey().toLowerCase()
            + System.currentTimeMillis();
        String objectData = "Just some simple text data";
        S3Object object = new S3Object(
            "text data object : îüøæç : テストオブジェクト",
            objectData);
        object.addMetadata("my-test-metadata", "my-value");


        service.getOrCreateBucket(bucketName, "eu-central-1");

        service.putObject(bucketName, object);

        // After request targeted at our bucket, we should have a cache entry
        // mapping our bucket name to the correct region.
        assertEquals(
            "eu-central-1", service.getRegionEndpointCache().get(bucketName));

        // With a cached mapping to the correct region, a HEAD request to
        // non-default region bucket using a service that is not aware of the
        // region will succeed.
        S3Object headObject = (S3Object)service.getObjectDetails(
            bucketName, object.getKey());
        assertEquals("my-value", headObject.getMetadata("my-test-metadata"));

        // The same HEAD request to non-default region bucket using a service
        // that is not aware of the region would fail if it wasn't for the
        // cached mapping from bucket to region.
        service.getRegionEndpointCache().remove(bucketName);
        try {
            service.getObjectDetails(bucketName, object.getKey());
            fail("Expected HEAD request to fail with no");
        } catch (ServiceException e) {
        }

        // A GET request to non-default region bucket using a service that is not
        // aware of the region can succeed because we get an error from S3 with
        // the expected region, and can correct the request then retry.
        S3Object retrievedObject = service.getObject(bucketName, object.getKey());
        assertEquals(objectData,
            ServiceUtils.readInputStreamToString(
                retrievedObject.getDataInputStream(),
                Constants.DEFAULT_ENCODING));

        // The above GET request targeted at our bucket could be made to succeed
        // using the error data returned by S3, which also re-populates our
        // bucket name to region cache.
        assertEquals(
            "eu-central-1", service.getRegionEndpointCache().get(bucketName));

        service.deleteObject(bucketName, object.getKey());

        service.deleteBucket(bucketName);
    }

}
TOP

Related Classes of org.jets3t.service.TestAWSRequestSignatureVersion4

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.