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(); }
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', gmdate(DateFormat::RFC1123, $this->getTimestamp())); } // 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 = (string) ($request->getHeader('Date') ?: $request->getHeader('x-amz-date')); $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)); }
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 addQueryValues($scope, RequestInterface $request, CredentialsInterface $credentials, $expires) { $credential = $credentials->getAccessKeyId() . '/' . $scope; // Set query params required for pre-signed URLs $request->getQuery()->set('X-Amz-Algorithm', 'AWS4-HMAC-SHA256')->set('X-Amz-Credential', $credential)->set('X-Amz-Date', gmdate('Ymd\\THis\\Z', $this->getTimestamp()))->set('X-Amz-SignedHeaders', 'Host')->set('X-Amz-Expires', $this->convertExpires($expires)); }