mirror of https://github.com/apache/jclouds.git
JCLOUDS-255: Support S3 signed URLs with expiry
Mostly code motion from AWSS3BlobRequestSigner to S3BlobRequestSigner with some additional cleanups.
This commit is contained in:
parent
24f961eac2
commit
7a110b31ba
|
@ -33,6 +33,7 @@ import org.jclouds.rest.internal.RestAnnotationProcessor;
|
|||
import org.jclouds.s3.S3Client;
|
||||
import org.jclouds.s3.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.s3.domain.S3Object;
|
||||
import org.jclouds.s3.filters.RequestAuthorizeSignature;
|
||||
import org.jclouds.s3.options.PutObjectOptions;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
@ -40,6 +41,8 @@ import com.google.common.reflect.Invokable;
|
|||
|
||||
@Singleton
|
||||
public class S3BlobRequestSigner<T extends S3Client> implements BlobRequestSigner {
|
||||
private final RequestAuthorizeSignature authSigner;
|
||||
|
||||
protected final RestAnnotationProcessor processor;
|
||||
protected final BlobToObject blobToObject;
|
||||
protected final BlobToHttpGetOptions blob2HttpGetOptions;
|
||||
|
@ -50,14 +53,16 @@ public class S3BlobRequestSigner<T extends S3Client> implements BlobRequestSigne
|
|||
|
||||
@Inject
|
||||
public S3BlobRequestSigner(RestAnnotationProcessor processor, BlobToObject blobToObject,
|
||||
BlobToHttpGetOptions blob2HttpGetOptions, Class<T> interfaceClass) throws SecurityException,
|
||||
NoSuchMethodException {
|
||||
BlobToHttpGetOptions blob2HttpGetOptions, Class<T> interfaceClass,
|
||||
RequestAuthorizeSignature authSigner)
|
||||
throws SecurityException, NoSuchMethodException {
|
||||
this.processor = checkNotNull(processor, "processor");
|
||||
this.blobToObject = checkNotNull(blobToObject, "blobToObject");
|
||||
this.blob2HttpGetOptions = checkNotNull(blob2HttpGetOptions, "blob2HttpGetOptions");
|
||||
this.getMethod = method(interfaceClass, "getObject", String.class, String.class, GetOptions[].class);
|
||||
this.deleteMethod = method(interfaceClass, "deleteObject", String.class, String.class);
|
||||
this.createMethod = method(interfaceClass, "putObject", String.class, S3Object.class, PutObjectOptions[].class);
|
||||
this.authSigner = authSigner;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -69,7 +74,10 @@ public class S3BlobRequestSigner<T extends S3Client> implements BlobRequestSigne
|
|||
|
||||
@Override
|
||||
public HttpRequest signGetBlob(String container, String name, long timeInSeconds) {
|
||||
throw new UnsupportedOperationException();
|
||||
checkNotNull(container, "container");
|
||||
checkNotNull(name, "name");
|
||||
HttpRequest request = processor.apply(Invocation.create(getMethod, ImmutableList.<Object> of(container, name)));
|
||||
return cleanRequest(authSigner.signForTemporaryAccess(request, timeInSeconds));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -82,7 +90,11 @@ public class S3BlobRequestSigner<T extends S3Client> implements BlobRequestSigne
|
|||
|
||||
@Override
|
||||
public HttpRequest signPutBlob(String container, Blob blob, long timeInSeconds) {
|
||||
throw new UnsupportedOperationException();
|
||||
checkNotNull(container, "container");
|
||||
checkNotNull(blob, "blob");
|
||||
HttpRequest request = processor.apply(Invocation.create(createMethod,
|
||||
ImmutableList.<Object>of(container, blobToObject.apply(blob))));
|
||||
return cleanRequest(authSigner.signForTemporaryAccess(request, timeInSeconds));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
*/
|
||||
package org.jclouds.s3.filters;
|
||||
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
|
||||
/**
|
||||
|
@ -23,4 +24,5 @@ import org.jclouds.http.HttpRequestFilter;
|
|||
*/
|
||||
|
||||
public interface RequestAuthorizeSignature extends HttpRequestFilter {
|
||||
HttpRequest signForTemporaryAccess(HttpRequest request, long timeInSeconds);
|
||||
}
|
||||
|
|
|
@ -29,9 +29,11 @@ import static org.jclouds.s3.reference.S3Constants.PROPERTY_S3_VIRTUAL_HOST_BUCK
|
|||
import static org.jclouds.util.Strings2.toInputStream;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.inject.Inject;
|
||||
|
@ -42,14 +44,17 @@ import javax.inject.Singleton;
|
|||
import org.jclouds.Constants;
|
||||
import org.jclouds.aws.domain.SessionCredentials;
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpException;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.http.HttpRequestFilter;
|
||||
import org.jclouds.http.HttpUtils;
|
||||
import org.jclouds.http.internal.SignatureWire;
|
||||
import org.jclouds.logging.Logger;
|
||||
import org.jclouds.rest.RequestSigner;
|
||||
import org.jclouds.s3.reference.S3Constants;
|
||||
import org.jclouds.s3.util.S3Utils;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
|
@ -90,13 +95,15 @@ public class RequestAuthorizeSignatureV2 implements RequestAuthorizeSignature, R
|
|||
private final String headerTag;
|
||||
private final String servicePath;
|
||||
private final boolean isVhostStyle;
|
||||
private final DateService dateService;
|
||||
|
||||
@Inject
|
||||
public RequestAuthorizeSignatureV2(SignatureWire signatureWire, @Named(PROPERTY_AUTH_TAG) String authTag,
|
||||
@Named(PROPERTY_S3_VIRTUAL_HOST_BUCKETS) boolean isVhostStyle,
|
||||
@Named(PROPERTY_S3_SERVICE_PATH) String servicePath, @Named(PROPERTY_HEADER_TAG) String headerTag,
|
||||
@org.jclouds.location.Provider Supplier<Credentials> creds,
|
||||
@TimeStamp Provider<String> timeStampProvider, Crypto crypto, HttpUtils utils) {
|
||||
@TimeStamp Provider<String> timeStampProvider, Crypto crypto, HttpUtils utils,
|
||||
DateService dateService) {
|
||||
this.isVhostStyle = isVhostStyle;
|
||||
this.servicePath = servicePath;
|
||||
this.headerTag = headerTag;
|
||||
|
@ -106,6 +113,7 @@ public class RequestAuthorizeSignatureV2 implements RequestAuthorizeSignature, R
|
|||
this.timeStampProvider = timeStampProvider;
|
||||
this.crypto = crypto;
|
||||
this.utils = utils;
|
||||
this.dateService = dateService;
|
||||
}
|
||||
|
||||
public HttpRequest filter(HttpRequest request) throws HttpException {
|
||||
|
@ -261,4 +269,32 @@ public class RequestAuthorizeSignatureV2 implements RequestAuthorizeSignature, R
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpRequest signForTemporaryAccess(HttpRequest request, long timeInSeconds) {
|
||||
// Update the 'DATE' header
|
||||
String dateString = request.getFirstHeaderOrNull(HttpHeaders.DATE);
|
||||
if (dateString == null) {
|
||||
dateString = timeStampProvider.get();
|
||||
}
|
||||
Date date = dateService.rfc1123DateParse(dateString);
|
||||
String expiration = String.valueOf(TimeUnit.MILLISECONDS.toSeconds(date.getTime()) + timeInSeconds);
|
||||
HttpRequest.Builder<?> builder = request.toBuilder()
|
||||
.removeHeader(HttpHeaders.AUTHORIZATION)
|
||||
.replaceHeader(HttpHeaders.DATE, expiration);
|
||||
String stringToSign = createStringToSign(builder.build());
|
||||
String signature = sign(stringToSign);
|
||||
HttpRequest ret = builder
|
||||
.addQueryParam(HttpHeaders.EXPIRES, expiration)
|
||||
.addQueryParam("AWSAccessKeyId", creds.get().identity)
|
||||
// Signature MUST be the last parameter because if it isn't, even encoded '+' values in the
|
||||
// signature will be converted to a space by a subsequent addQueryParameter.
|
||||
// See HttpRequestTest.testAddBase64AndUrlEncodedQueryParams for more details.
|
||||
.addQueryParam(S3Constants.TEMPORARY_SIGNATURE_PARAM, signature)
|
||||
// remove signer created by RestAnnotationProcessor
|
||||
.removeHeader(HttpHeaders.DATE)
|
||||
.filters(ImmutableList.<HttpRequestFilter>of())
|
||||
.build();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ public class RequestAuthorizeSignatureV4 implements RequestAuthorizeSignature {
|
|||
* For example, you might store videos in an Amazon S3 bucket and make them available on your website by using presigned URLs.
|
||||
* Identifies the version of AWS Signature and the algorithm that you used to calculate the signature.
|
||||
*/
|
||||
@Override
|
||||
public HttpRequest signForTemporaryAccess(HttpRequest request, long timeInSeconds) {
|
||||
return signerForQueryString.sign(request, timeInSeconds);
|
||||
}
|
||||
|
|
|
@ -33,6 +33,8 @@ public final class S3Constants {
|
|||
public static final String PROPERTY_S3_VIRTUAL_HOST_BUCKETS = "jclouds.s3.virtual-host-buckets";
|
||||
public static final String PROPERTY_JCLOUDS_S3_CHUNKED_SIZE = "jclouds.s3.chunked.size";
|
||||
|
||||
public static final String TEMPORARY_SIGNATURE_PARAM = "Signature";
|
||||
|
||||
private S3Constants() {
|
||||
throw new AssertionError("intentionally unimplemented");
|
||||
}
|
||||
|
|
|
@ -16,13 +16,10 @@
|
|||
*/
|
||||
package org.jclouds.s3.blobstore.integration;
|
||||
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobSignerLiveTest;
|
||||
import org.jclouds.blobstore.integration.internal.BaseBlobStoreIntegrationTest;
|
||||
import org.testng.SkipException;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@Test(groups = "live", testName = "S3BlobSignerLiveTest")
|
||||
|
@ -33,59 +30,17 @@ public class S3BlobSignerLiveTest extends BaseBlobSignerLiveTest {
|
|||
BaseBlobStoreIntegrationTest.SANITY_CHECK_RETURNED_BUCKET_NAME = true;
|
||||
}
|
||||
|
||||
protected boolean supportsUrlWithTime() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignGetUrlWithTime() throws InterruptedException, IOException {
|
||||
try {
|
||||
super.testSignGetUrlWithTime();
|
||||
if (!supportsUrlWithTime()) {
|
||||
fail();
|
||||
}
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
throw new SkipException("not supported by S3 signer", uoe);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignGetUrlWithTimeExpired() throws InterruptedException, IOException {
|
||||
try {
|
||||
// Intentionally try with a timeout of 0. AWS signature v4 throws an error if
|
||||
// the timeout is negative.
|
||||
super.testSignGetUrlWithTime(/*timeout=*/ 0);
|
||||
if (!supportsUrlWithTime()) {
|
||||
fail();
|
||||
}
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
throw new SkipException("not supported by S3 signer", uoe);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignPutUrlWithTime() throws Exception {
|
||||
try {
|
||||
super.testSignPutUrlWithTime();
|
||||
if (!supportsUrlWithTime()) {
|
||||
fail();
|
||||
}
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
throw new SkipException("not supported by S3 signer", uoe);
|
||||
}
|
||||
// Intentionally try with a timeout of 0. AWS signature v4 throws an error if
|
||||
// the timeout is negative.
|
||||
super.testSignGetUrlWithTime(/*timeout=*/ 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSignPutUrlWithTimeExpired() throws Exception {
|
||||
try {
|
||||
// Intentionally try with a timeout of 0. AWS signature v4 throws an error if
|
||||
// the timeout is negative.
|
||||
super.testSignPutUrlWithTime(/*timeout=*/ 0);
|
||||
if (!supportsUrlWithTime()) {
|
||||
fail();
|
||||
}
|
||||
} catch (UnsupportedOperationException uoe) {
|
||||
throw new SkipException("not supported by S3 signer", uoe);
|
||||
}
|
||||
// Intentionally try with a timeout of 0. AWS signature v4 throws an error if
|
||||
// the timeout is negative.
|
||||
super.testSignPutUrlWithTime(/*timeout=*/ 0);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,102 +0,0 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jclouds.aws.s3.blobstore;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static org.jclouds.blobstore.util.BlobStoreUtils.cleanRequest;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.jclouds.aws.s3.AWSS3Client;
|
||||
import org.jclouds.blobstore.domain.Blob;
|
||||
import org.jclouds.blobstore.functions.BlobToHttpGetOptions;
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
import org.jclouds.reflect.Invocation;
|
||||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||
import org.jclouds.s3.blobstore.S3BlobRequestSigner;
|
||||
import org.jclouds.s3.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.s3.filters.RequestAuthorizeSignatureV2;
|
||||
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provider;
|
||||
|
||||
public class AWSS3BlobRequestSigner extends S3BlobRequestSigner<AWSS3Client> {
|
||||
public static final String TEMPORARY_SIGNATURE_PARAM = "Signature";
|
||||
|
||||
private final RequestAuthorizeSignatureV2 authSigner;
|
||||
private final String identity;
|
||||
private final DateService dateService;
|
||||
private final Provider<String> timeStampProvider;
|
||||
|
||||
@Inject
|
||||
public AWSS3BlobRequestSigner(RestAnnotationProcessor processor, BlobToObject blobToObject,
|
||||
BlobToHttpGetOptions blob2HttpGetOptions, Class<AWSS3Client> interfaceClass,
|
||||
@org.jclouds.location.Provider Supplier<Credentials> credentials,
|
||||
RequestAuthorizeSignatureV2 authSigner, @TimeStamp Provider<String> timeStampProvider,
|
||||
DateService dateService) throws SecurityException, NoSuchMethodException {
|
||||
super(processor, blobToObject, blob2HttpGetOptions, interfaceClass);
|
||||
this.authSigner = authSigner;
|
||||
this.identity = credentials.get().identity;
|
||||
this.dateService = dateService;
|
||||
this.timeStampProvider = timeStampProvider;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpRequest signGetBlob(String container, String name, long timeInSeconds) {
|
||||
checkNotNull(container, "container");
|
||||
checkNotNull(name, "name");
|
||||
HttpRequest request = processor.apply(Invocation.create(getMethod, ImmutableList.<Object> of(container, name)));
|
||||
return cleanRequest(signForTemporaryAccess(request, timeInSeconds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpRequest signPutBlob(String container, Blob blob, long timeInSeconds) {
|
||||
checkNotNull(container, "container");
|
||||
checkNotNull(blob, "blob");
|
||||
HttpRequest request = processor.apply(Invocation.create(createMethod,
|
||||
ImmutableList.<Object>of(container, blobToObject.apply(blob))));
|
||||
return cleanRequest(signForTemporaryAccess(request, timeInSeconds));
|
||||
}
|
||||
|
||||
private HttpRequest signForTemporaryAccess(HttpRequest request, long timeInSeconds) {
|
||||
// Update the 'DATE' header
|
||||
String dateString = request.getFirstHeaderOrNull(HttpHeaders.DATE);
|
||||
if (dateString == null) {
|
||||
dateString = timeStampProvider.get();
|
||||
}
|
||||
Date date = dateService.rfc1123DateParse(dateString);
|
||||
String expiration = String.valueOf(TimeUnit.MILLISECONDS.toSeconds(date.getTime()) + timeInSeconds);
|
||||
HttpRequest.Builder<?> builder = request.toBuilder().replaceHeader(HttpHeaders.DATE, expiration);
|
||||
String stringToSign = authSigner.createStringToSign(builder.build());
|
||||
String signature = authSigner.sign(stringToSign);
|
||||
HttpRequest ret = builder.addQueryParam(HttpHeaders.EXPIRES, expiration)
|
||||
.addQueryParam("AWSAccessKeyId", identity)
|
||||
// Signature MUST be the last parameter because if it isn't, even encoded '+' values in the
|
||||
// signature will be converted to a space by a subsequent addQueryParameter.
|
||||
// See HttpRequestTest.testAddBase64AndUrlEncodedQueryParams for more details.
|
||||
.addQueryParam(TEMPORARY_SIGNATURE_PARAM, signature)
|
||||
.build();
|
||||
return ret;
|
||||
}
|
||||
}
|
|
@ -28,20 +28,20 @@ import org.jclouds.reflect.Invocation;
|
|||
import org.jclouds.rest.internal.RestAnnotationProcessor;
|
||||
import org.jclouds.s3.blobstore.S3BlobRequestSigner;
|
||||
import org.jclouds.s3.blobstore.functions.BlobToObject;
|
||||
import org.jclouds.s3.filters.RequestAuthorizeSignatureV4;
|
||||
import org.jclouds.s3.filters.RequestAuthorizeSignature;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
public class AWSS3BlobRequestSignerV4 extends S3BlobRequestSigner<AWSS3Client> {
|
||||
|
||||
private final RequestAuthorizeSignatureV4 authSigner;
|
||||
private final RequestAuthorizeSignature authSigner;
|
||||
|
||||
@Inject
|
||||
public AWSS3BlobRequestSignerV4(RestAnnotationProcessor processor, BlobToObject blobToObject,
|
||||
BlobToHttpGetOptions blob2HttpGetOptions, Class<AWSS3Client> interfaceClass,
|
||||
RequestAuthorizeSignatureV4 authSigner) throws SecurityException, NoSuchMethodException {
|
||||
super(processor, blobToObject, blob2HttpGetOptions, interfaceClass);
|
||||
RequestAuthorizeSignature authSigner) throws SecurityException, NoSuchMethodException {
|
||||
super(processor, blobToObject, blob2HttpGetOptions, interfaceClass, authSigner);
|
||||
this.authSigner = authSigner;
|
||||
}
|
||||
|
||||
|
|
|
@ -18,10 +18,10 @@ package org.jclouds.aws.s3.filters;
|
|||
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_AUTH_TAG;
|
||||
import static org.jclouds.aws.reference.AWSConstants.PROPERTY_HEADER_TAG;
|
||||
import static org.jclouds.aws.s3.blobstore.AWSS3BlobRequestSigner.TEMPORARY_SIGNATURE_PARAM;
|
||||
import static org.jclouds.http.utils.Queries.queryParser;
|
||||
import static org.jclouds.s3.reference.S3Constants.PROPERTY_S3_SERVICE_PATH;
|
||||
import static org.jclouds.s3.reference.S3Constants.PROPERTY_S3_VIRTUAL_HOST_BUCKETS;
|
||||
import static org.jclouds.s3.reference.S3Constants.TEMPORARY_SIGNATURE_PARAM;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
|
@ -29,6 +29,7 @@ import javax.inject.Provider;
|
|||
import javax.inject.Singleton;
|
||||
|
||||
import org.jclouds.crypto.Crypto;
|
||||
import org.jclouds.date.DateService;
|
||||
import org.jclouds.date.TimeStamp;
|
||||
import org.jclouds.domain.Credentials;
|
||||
import org.jclouds.http.HttpRequest;
|
||||
|
@ -47,9 +48,10 @@ public class AWSRequestAuthorizeSignature extends RequestAuthorizeSignatureV2 {
|
|||
@Named(PROPERTY_S3_VIRTUAL_HOST_BUCKETS) boolean isVhostStyle,
|
||||
@Named(PROPERTY_S3_SERVICE_PATH) String servicePath, @Named(PROPERTY_HEADER_TAG) String headerTag,
|
||||
@org.jclouds.location.Provider Supplier<Credentials> creds,
|
||||
@TimeStamp Provider<String> timeStampProvider, Crypto crypto, HttpUtils utils) {
|
||||
@TimeStamp Provider<String> timeStampProvider, Crypto crypto, HttpUtils utils,
|
||||
DateService dateService) {
|
||||
super(signatureWire, authTag, isVhostStyle, servicePath, headerTag, creds, timeStampProvider, crypto,
|
||||
utils);
|
||||
utils, dateService);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
package org.jclouds.aws.s3.filters;
|
||||
|
||||
import static org.jclouds.http.utils.Queries.queryParser;
|
||||
import static org.jclouds.aws.s3.blobstore.AWSS3BlobRequestSigner.TEMPORARY_SIGNATURE_PARAM;
|
||||
import static org.jclouds.s3.filters.AwsSignatureV4Constants.AMZ_SIGNATURE_PARAM;
|
||||
import static org.jclouds.s3.reference.S3Constants.TEMPORARY_SIGNATURE_PARAM;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
|
|
@ -35,9 +35,4 @@ public class AWSS3BlobSignerLiveTest extends S3BlobSignerLiveTest {
|
|||
overrides.setProperty(Constants.PROPERTY_SESSION_INTERVAL, "1");
|
||||
return overrides;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean supportsUrlWithTime() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue