/** * {@inheritdoc} */ public function signRequest(RequestInterface $request, CredentialsInterface $credentials) { // Refresh the cached timestamp $this->getTimestamp(true); // Add default headers $request->setHeader('x-amz-date', $this->getDateTime(DateFormat::RFC1123)); // Add the security token if one is present if ($credentials->getSecurityToken()) { $request->setHeader('x-amz-security-token', $credentials->getSecurityToken()); } // Grab the path and ensure that it is absolute $path = '/' . ltrim($request->getUrl(true)->normalizePath()->getPath(), '/'); // Begin building the string to sign $sign = $request->getMethod() . "\n" . "{$path}\n" . $this->getCanonicalizedQueryString($request) . "\n"; // Get all of the headers that must be signed (host and x-amz-*) $headers = $this->getHeadersToSign($request); foreach ($headers as $key => $value) { $sign .= $key . ':' . $value . "\n"; } $sign .= "\n"; // Add the body of the request if a body is present if ($request instanceof EntityEnclosingRequestInterface) { $sign .= (string) $request->getBody(); } // Add the string to sign to the request for debugging purposes $request->getParams()->set('aws.string_to_sign', $sign); $signature = base64_encode(hash_hmac('sha256', hash('sha256', $sign, true), $credentials->getSecretKey(), true)); // Add the authorization header to the request $request->setHeader('x-amzn-authorization', sprintf('AWS3 AWSAccessKeyId=%s,Algorithm=HmacSHA256,SignedHeaders=%s,Signature=%s', $credentials->getAccessKeyId(), implode(';', array_keys($headers)), $signature)); }
public function createPresignedUrl(RequestInterface $request, CredentialsInterface $credentials, $expires) { if ($expires instanceof \DateTime) { $expires = $expires->getTimestamp(); } elseif (!is_numeric($expires)) { $expires = strtotime($expires); } // Operate on a clone of the request, so the original is not altered $request = clone $request; // URL encoding already occurs in the URI template expansion. Undo that and encode using the same encoding as // GET object, PUT object, etc. $path = S3Client::encodeKey(rawurldecode($request->getPath())); $request->setPath($path); // Make sure to handle temporary credentials if ($token = $credentials->getSecurityToken()) { $request->setHeader('x-amz-security-token', $token); $request->getQuery()->set('x-amz-security-token', $token); } // Set query params required for pre-signed URLs $request->getQuery()->set('AWSAccessKeyId', $credentials->getAccessKeyId())->set('Expires', $expires)->set('Signature', $this->signString($this->createCanonicalizedString($request, $expires), $credentials)); // Move X-Amz-* headers to the query string foreach ($request->getHeaders() as $name => $header) { $name = strtolower($name); if (strpos($name, 'x-amz-') === 0) { $request->getQuery()->set($name, (string) $header); $request->removeHeader($name); } } return $request->getUrl(); }
/** * {@inheritdoc} */ public function signRequest(RequestInterface $request, CredentialsInterface $credentials) { // Add a date header if one is not set if (!$request->hasHeader('date') && !$request->hasHeader('x-amz-date')) { $request->setHeader('Date', $this->getDateTime(DateFormat::RFC1123)); } // Add the security token if one is present if ($credentials->getSecurityToken()) { $request->setHeader('x-amz-security-token', $credentials->getSecurityToken()); } // Determine the string to sign $stringToSign = $request->getHeader('Date', true) ?: $request->getHeader('x-amz-date', true); $request->getParams()->set('aws.string_to_sign', $stringToSign); // Calculate the signature $signature = base64_encode(hash_hmac('sha256', $stringToSign, $credentials->getSecretKey(), true)); // Add the authorization header to the request $headerFormat = 'AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=HmacSHA256,Signature=%s'; $request->setHeader('X-Amzn-Authorization', sprintf($headerFormat, $credentials->getAccessKeyId(), $signature)); }
/** * {@inheritdoc} */ public function signRequest(RequestInterface $request, CredentialsInterface $credentials) { // Add the security token header if one is being used by the credentials if ($token = $credentials->getSecurityToken()) { $request->setHeader('x-amz-security-token', $token); } // Add a date header if one is not set if (!$request->hasHeader('date') && !$request->hasHeader('x-amz-date')) { $request->setHeader('Date', gmdate(DateFormat::RFC2822)); } $stringToSign = $this->createCanonicalizedString($request); $request->getParams()->set('aws.string_to_sign', $stringToSign); $request->setHeader('Authorization', 'AWS ' . $credentials->getAccessKeyId() . ':' . $this->signString($stringToSign, $credentials)); }
public function createPresignedUrl(RequestInterface $request, CredentialsInterface $credentials, $expires) { $request = clone $request; // Make sure to handle temporary credentials if ($token = $credentials->getSecurityToken()) { $request->setHeader('X-Amz-Security-Token', $token); $request->getQuery()->set('X-Amz-Security-Token', $token); } $this->moveHeadersToQuery($request); $httpDate = $request->getQuery()->get('X-Amz-Date'); $scopeDate = substr($httpDate, 0, 8); $scope = "{$scopeDate}/{$this->regionName}/s3/aws4_request"; $credential = $credentials->getAccessKeyId() . '/' . $scope; $this->addQueryStringValues($request, $credential, $this->convertExpires($expires)); $context = $this->createSigningContext($request, 'UNSIGNED-PAYLOAD'); $signingKey = $this->getSigningKey($scopeDate, $this->regionName, $this->serviceName, $credentials->getSecretKey()); $stringToSign = "AWS4-HMAC-SHA256\n{$httpDate}\n{$scope}\n" . hash('sha256', $context['canonical_request']); $request->getQuery()->set('X-Amz-Signature', hash_hmac('sha256', $stringToSign, $signingKey)); return $request->getUrl(); }
public function signRequest(RequestInterface $request, CredentialsInterface $credentials) { // refresh the cached timestamp $timestamp = $this->getTimestamp(true); // set values we need in CanonicalizedParameterString $this->addParameter($request, 'Timestamp', gmdate('c', $timestamp)); $this->addParameter($request, 'SignatureVersion', '2'); $this->addParameter($request, 'SignatureMethod', 'HmacSHA256'); $this->addParameter($request, 'AWSAccessKeyId', $credentials->getAccessKeyId()); if ($token = $credentials->getSecurityToken()) { $this->addParameter($request, 'SecurityToken', $token); } // Get the path and ensure it's absolute $path = '/' . ltrim($request->getUrl(true)->normalizePath()->getPath(), '/'); // build string to sign $sign = $request->getMethod() . "\n" . $request->getHost() . "\n" . $path . "\n" . $this->getCanonicalizedParameterString($request); // Add the string to sign to the request for debugging purposes $request->getParams()->set('aws.string_to_sign', $sign); $signature = base64_encode(hash_hmac('sha256', $sign, $credentials->getSecretKey(), true)); $this->addParameter($request, 'Signature', $signature); }
private function createPresignedRequest(RequestInterface $request, CredentialsInterface $credentials) { $sr = RequestFactory::getInstance()->cloneRequestWithMethod($request, 'GET'); // Move POST fields to the query if they are present if ($request instanceof EntityEnclosingRequestInterface) { foreach ($request->getPostFields() as $name => $value) { $sr->getQuery()->set($name, $value); } } // Make sure to handle temporary credentials if ($token = $credentials->getSecurityToken()) { $sr->setHeader('X-Amz-Security-Token', $token); $sr->getQuery()->set('X-Amz-Security-Token', $token); } $this->moveHeadersToQuery($sr); return $sr; }
public function signRequest(RequestInterface $request, CredentialsInterface $credentials) { $timestamp = $this->getTimestamp(); $longDate = gmdate(DateFormat::ISO8601, $timestamp); $shortDate = substr($longDate, 0, 8); // Remove any previously set Authorization headers so that retries work $request->removeHeader('Authorization'); // Requires a x-amz-date header or Date if ($request->hasHeader('x-amz-date') || !$request->hasHeader('Date')) { $request->setHeader('x-amz-date', $longDate); } else { $request->setHeader('Date', gmdate(DateFormat::RFC1123, $timestamp)); } // Add the security token if one is present if ($credentials->getSecurityToken()) { $request->setHeader('x-amz-security-token', $credentials->getSecurityToken()); } // Parse the service and region or use one that is explicitly set $region = $this->regionName; $service = $this->serviceName; if (!$region || !$service) { $url = Url::factory($request->getUrl()); $region = $region ?: HostNameUtils::parseRegionName($url); $service = $service ?: HostNameUtils::parseServiceName($url); } $credentialScope = "{$shortDate}/{$region}/{$service}/aws4_request"; // Calculate the request signature payload if ($request->hasHeader('x-amz-content-sha256')) { // Handle streaming operations (e.g. Glacier.UploadArchive) $payload = $request->getHeader('x-amz-content-sha256'); } elseif ($request instanceof EntityEnclosingRequestInterface) { $payload = hash('sha256', $request->getMethod() == 'POST' && count($request->getPostFields()) ? (string) $request->getPostFields() : (string) $request->getBody()); } else { // Use the default payload if there is no body $payload = self::DEFAULT_PAYLOAD; } $signingContext = $this->createSigningContext($request, $payload); $signingContext['string_to_sign'] = "AWS4-HMAC-SHA256\n{$longDate}\n{$credentialScope}\n" . hash('sha256', $signingContext['canonical_request']); // Calculate the signing key using a series of derived keys $signingKey = $this->getSigningKey($shortDate, $region, $service, $credentials->getSecretKey()); $signature = hash_hmac('sha256', $signingContext['string_to_sign'], $signingKey); $request->setHeader('Authorization', "AWS4-HMAC-SHA256 " . "Credential={$credentials->getAccessKeyId()}/{$credentialScope}, " . "SignedHeaders={$signingContext['signed_headers']}, Signature={$signature}"); // Add debug information to the request $request->getParams()->set('aws.signature', $signingContext); }
/** * {@inheritdoc} */ public function signRequest(RequestInterface $request, CredentialsInterface $credentials) { // Refresh the cached timestamp $this->getTimestamp(true); $longDate = $this->getDateTime(DateFormat::ISO8601); $shortDate = $this->getDateTime(DateFormat::SHORT); // Remove any previously set Authorization headers so that // exponential backoff works correctly $request->removeHeader('Authorization'); // Requires a x-amz-date header or Date if ($request->hasHeader('x-amz-date') || !$request->hasHeader('Date')) { $request->setHeader('x-amz-date', $longDate); } else { $request->setHeader('Date', $this->getDateTime(DateFormat::RFC1123)); } // Add the security token if one is present if ($credentials->getSecurityToken()) { $request->setHeader('x-amz-security-token', $credentials->getSecurityToken()); } // Parse the service and region or use one that is explicitly set $url = null; if (!$this->regionName || !$this->serviceName) { $url = Url::factory($request->getUrl()); } if (!($region = $this->regionName)) { $region = HostNameUtils::parseRegionName($url); } if (!($service = $this->serviceName)) { $service = HostNameUtils::parseServiceName($url); } $credentialScope = "{$shortDate}/{$region}/{$service}/aws4_request"; $signingContext = $this->createCanonicalRequest($request); $signingContext['string_to_sign'] = "AWS4-HMAC-SHA256\n{$longDate}\n{$credentialScope}\n" . hash('sha256', $signingContext['canonical_request']); // Calculate the signing key using a series of derived keys $signingKey = $this->getSigningKey($shortDate, $region, $service, $credentials->getSecretKey()); $signature = hash_hmac('sha256', $signingContext['string_to_sign'], $signingKey); $request->setHeader('Authorization', "AWS4-HMAC-SHA256 " . "Credential={$credentials->getAccessKeyId()}/{$credentialScope}, " . "SignedHeaders={$signingContext['signed_headers']}, Signature={$signature}"); // Add debug information to the request $request->getParams()->set('aws.signature', $signingContext); }
private function createPresignedRequest(RequestInterface $request, CredentialsInterface $credentials) { // POST requests can be sent as GET requests instead by moving the // POST fields into the query string. if ($request instanceof EntityEnclosingRequestInterface && $request->getMethod() === 'POST' && strpos($request->getHeader('Content-Type'), 'application/x-www-form-urlencoded') === 0) { $sr = RequestFactory::getInstance()->cloneRequestWithMethod($request, 'GET'); // Move POST fields to the query if they are present foreach ($request->getPostFields() as $name => $value) { $sr->getQuery()->set($name, $value); } } else { $sr = clone $request; } // Make sure to handle temporary credentials if ($token = $credentials->getSecurityToken()) { $sr->setHeader('X-Amz-Security-Token', $token); $sr->getQuery()->set('X-Amz-Security-Token', $token); } $this->moveHeadersToQuery($sr); return $sr; }