/** * Generates an instance of AWS4signerRequestParams that holds the * parameters used for computing a AWS 4 signature for a request */ public AWS4SignerRequestParams(SignableRequest<?> request, Date signingDateOverride, String regionNameOverride, String serviceName, String signingAlgorithm) { if (request == null) { throw new IllegalArgumentException("Request cannot be null"); } if (signingAlgorithm == null) { throw new IllegalArgumentException( "Signing Algorithm cannot be null"); } this.request = request; this.signingDateTimeMilli = signingDateOverride != null ? signingDateOverride .getTime() : getSigningDate(request); this.formattedSigningDate = AWS4SignerUtils .formatDateStamp(signingDateTimeMilli); this.serviceName = serviceName; this.regionName = regionNameOverride != null ? regionNameOverride : AwsHostNameUtils.parseRegionName(request.getEndpoint() .getHost(), this.serviceName); this.scope = generateScope(request, formattedSigningDate, this.serviceName, regionName); this.formattedSigningDateTime = AWS4SignerUtils .formatTimestamp(signingDateTimeMilli); this.signingAlgorithm = signingAlgorithm; }
/** * @deprecated use {@link AmazonS3ClientBuilder#setEndpointConfiguration(AwsClientBuilder.EndpointConfiguration)} */ @Override @Deprecated public synchronized void setEndpoint(String endpoint) { if (ServiceUtils.isS3AccelerateEndpoint(endpoint)) { throw new IllegalStateException("To enable accelerate mode, please use AmazonS3ClientBuilder.withAccelerateModeEnabled(true)"); } else { super.setEndpoint(endpoint); /* * Extract the region string from the endpoint if it's not known to be a * global S3 endpoint. */ if (!ServiceUtils.isS3USStandardEndpoint(endpoint)) { clientRegion = AwsHostNameUtils.parseRegionName(this.endpoint.getHost(), S3_SERVICE_NAME); } } }
private String getSigningRegionForRequestURI(URI uri) { String regionName = awsClient.getSignerRegionOverride(); if (regionName == null) { regionName = AwsHostNameUtils.parseRegion(uri.getHost(), awsClient.getServiceName()); } return regionName; }
@Override public Signer getSigner(SignerProviderContext signerProviderContext) { URI uri = signerProviderContext.getUri(); // Return the default signer if no URI is passed, the client is configured with region override, // or if we are hitting an accelerate endpoint. if (uri == null || ServiceUtils.isS3AccelerateEndpoint(uri.getHost()) || isSignerRegionOverrideSet()) { return signer; } if (signer instanceof RegionAwareSigner) { // Parse region name from the host component of the URL and // assign it to the signer RegionAwareSigner regionSigner = (RegionAwareSigner) signer; try { regionSigner.setRegionName(AwsHostNameUtils.parseRegionName( uri.getHost(), "s3")); } catch (RuntimeException e) { log.warn("Failed to parse the endpoint " + uri + ", and skip re-assigning the signer region", e); } } return signer; }
/** * Get or initialize the S3 client. * Note: this method must be synchronized because we're accessing the * {@link #s3Client} field and we're calling this method from a worker thread. * @return the S3 client */ private synchronized AmazonS3 getS3Client() { if (s3Client == null) { BasicAWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey); AmazonS3ClientBuilder builder = AmazonS3ClientBuilder .standard() .withCredentials(new AWSStaticCredentialsProvider(credentials)); if (forceSignatureV2) { ClientConfigurationFactory configFactory = new ClientConfigurationFactory(); ClientConfiguration config = configFactory.getConfig(); config.setSignerOverride("S3SignerType"); builder = builder.withClientConfiguration(config); } String endpoint = "http://" + host + ":" + port; String clientRegion = null; if (!ServiceUtils.isS3USStandardEndpoint(endpoint)) { clientRegion = AwsHostNameUtils.parseRegion(host, AmazonS3Client.S3_SERVICE_NAME); } builder = builder.withEndpointConfiguration(new EndpointConfiguration( endpoint, clientRegion)); builder = builder.withPathStyleAccessEnabled(pathStyleAccess); s3Client = builder.build(); } return s3Client; }
@VisibleForTesting static AwsClientBuilder.EndpointConfiguration getEndpointConfiguration(final Optional<String> endpoint, final String signingRegion) { Preconditions.checkArgument(endpoint != null, "must provide an optional endpoint and not null"); Preconditions.checkArgument(!Strings.isNullOrEmpty(signingRegion), "must provide a signing region"); final String expectedServiceEndpoint = "https://" + Region.getRegion(Regions.fromName(signingRegion)).getServiceEndpoint(AmazonDynamoDB.ENDPOINT_PREFIX); if (endpoint.isPresent() && !Strings.isNullOrEmpty(endpoint.get())) { final String regionParsedFromEndpoint = AwsHostNameUtils.parseRegion(endpoint.get(), AmazonDynamoDB.ENDPOINT_PREFIX); Preconditions.checkArgument(regionParsedFromEndpoint == null || signingRegion.equals(regionParsedFromEndpoint)); return new AwsClientBuilder.EndpointConfiguration(endpoint.get(), signingRegion); } else { //Regions.fromName will throw IllegalArgumentException if signingRegion is not valid. return new AwsClientBuilder.EndpointConfiguration(expectedServiceEndpoint, signingRegion); } }
@Override public Bucket createBucket(CreateBucketRequest createBucketRequest) throws SdkClientException, AmazonServiceException { createBucketRequest = beforeClientExecution(createBucketRequest); rejectNull(createBucketRequest, "The CreateBucketRequest parameter must be specified when creating a bucket"); String bucketName = createBucketRequest.getBucketName(); rejectNull(bucketName, "The bucket name parameter must be specified when creating a bucket"); bucketName = bucketName.trim(); String requestRegion = createBucketRequest.getRegion(); URI requestEndpoint = getCreateBucketEndpoint(requestRegion); BucketNameUtils.validateBucketName(bucketName); Request<CreateBucketRequest> request = createRequest(bucketName, null, createBucketRequest, HttpMethodName.PUT, requestEndpoint); //Add IBM Service Instance Id & Encryption to headers if ((null != this.awsCredentialsProvider ) && (this.awsCredentialsProvider.getCredentials() instanceof IBMOAuthCredentials)) { IBMOAuthCredentials oAuthCreds = (IBMOAuthCredentials)this.awsCredentialsProvider.getCredentials(); if (oAuthCreds.getServiceInstanceId() != null) { request.addHeader(Headers.IBM_SERVICE_INSTANCE_ID, oAuthCreds.getServiceInstanceId()); if (null != createBucketRequest.getEncryptionType()) { request.addHeader(Headers.IBM_SSE_KP_ENCRYPTION_ALGORITHM, createBucketRequest.getEncryptionType().getKmsEncryptionAlgorithm()); request.addHeader(Headers.IBM_SSE_KP_CUSTOMER_ROOT_KEY_CRN, createBucketRequest.getEncryptionType().getIBMSSEKMSCustomerRootKeyCrn()); } } } if (createBucketRequest.getAccessControlList() != null) { addAclHeaders(request, createBucketRequest.getAccessControlList()); } else if (createBucketRequest.getCannedAcl() != null) { request.addHeader(Headers.S3_CANNED_ACL, createBucketRequest.getCannedAcl().toString()); } /* * If we're talking to a region-specific endpoint other than the US, we * *must* specify a location constraint. Try to derive the region from * the endpoint. */ if (getSignerRegion() != null && !getSignerRegion().equals("us-east-1") && StringUtils.isNullOrEmpty(requestRegion)) { requestRegion = AwsHostNameUtils.parseRegion(requestEndpoint.getHost(), S3_SERVICE_NAME); } /* * We can only send the CreateBucketConfiguration if we're *not* * creating a bucket in the US region. */ if (requestRegion != null && !StringUtils.upperCase(requestRegion).equals(Region.US_Standard.toString())) { XmlWriter xml = new XmlWriter(); xml.start("CreateBucketConfiguration", "xmlns", Constants.XML_NAMESPACE); xml.start("LocationConstraint").value(requestRegion).end(); xml.end(); request.setContent(new ByteArrayInputStream(xml.getBytes())); } invoke(request, voidResponseHandler, bucketName, null); return new Bucket(bucketName); }
/** * Returns the signer for the given uri and the current client * configuration. * <p> * Note, however, the signer returned for S3 is incomplete at this stage as * the information on the S3 bucket and key is not yet known. * * @param signerRegionOverride * the overriding signer region; or null if there is none. * @param isRegionIdAsSignerParam * true if the "regionId" is used to configure the signer if * applicable; false if this method is called for the purpose of * purely setting the communication end point of this AWS client, * and therefore the "regionId" parameter will not be used * directly for configuring the signer. */ private Signer computeSignerByURI(URI uri, String signerRegionOverride, boolean isRegionIdAsSignerParam) { if (uri == null) { throw new IllegalArgumentException( "Endpoint is not set. Use setEndpoint to set an endpoint before performing any request."); } String service = getServiceNameIntern(); String region = AwsHostNameUtils.parseRegionName(uri.getHost(), service); return computeSignerByServiceRegion( service, region, signerRegionOverride, isRegionIdAsSignerParam); }