public function sign(Request $request, ApiKey $apiKey) { date_default_timezone_set(self::TIME_ZONE); $date = new \DateTime(); $timeStamp = $date->format(self::TIMESTAMP_FORMAT); $dateStamp = $date->format(self::DATE_FORMAT); $nonce = UUID::generate(UUID::UUID_RANDOM, UUID::FMT_STRING); $parsedUrl = parse_url($request->getResourceUrl()); // SAuthc1 requires that we sign the Host header so we // have to have it in the request by the time we sign. $hostHeader = $parsedUrl['host']; if (!RequestUtils::isDefaultPort($parsedUrl)) { $hostHeader .= ':' . $parsedUrl['port']; } $requestHeaders = $request->getHeaders(); unset($requestHeaders[self::STORMPATH_DATE_HEADER]); unset($requestHeaders[self::AUTHORIZATION_HEADER]); $requestHeaders[self::HOST_HEADER] = $hostHeader; $requestHeaders[self::STORMPATH_DATE_HEADER] = $timeStamp; $request->setHeaders($requestHeaders); $method = $request->getMethod(); $canonicalResourcePath = $this->canonicalizeResourcePath($parsedUrl['path']); $canonicalQueryString = $this->canonicalizeQueryString($request); $canonicalHeaderString = $this->canonicalizeHeaders($request); $signedHeadersString = $this->getSignedHeaders($request); $requestPayloadHashHex = $this->toHex($this->hashText($this->getRequestPayload($request))); $canonicalRequest = $method . self::NL . $canonicalResourcePath . self::NL . $canonicalQueryString . self::NL . $canonicalHeaderString . self::NL . $signedHeadersString . self::NL . $requestPayloadHashHex; $id = $apiKey->getId() . '/' . $dateStamp . '/' . $nonce . '/' . self::ID_TERMINATOR; $canonicalRequestHashHex = $this->toHex($this->hashText($canonicalRequest)); $stringToSign = self::ALGORITHM . self::NL . $timeStamp . self::NL . $id . self::NL . $canonicalRequestHashHex; // SAuthc1 uses a series of derived keys, formed by hashing different pieces of data $kSecret = $this->toUTF8(self::AUTHENTICATION_SCHEME . $apiKey->getSecret()); $kDate = $this->internalSign($dateStamp, $kSecret, self::DEFAULT_ALGORITHM); $kNonce = $this->internalSign($nonce, $kDate, self::DEFAULT_ALGORITHM); $kSigning = $this->internalSign(self::ID_TERMINATOR, $kNonce, self::DEFAULT_ALGORITHM); $signature = $this->internalSign($this->toUTF8($stringToSign), $kSigning, self::DEFAULT_ALGORITHM); $signatureHex = $this->toHex($signature); $authorizationHeader = self::AUTHENTICATION_SCHEME . ' ' . $this->createNameValuePair(self::SAUTHC1_ID, $id) . ', ' . $this->createNameValuePair(self::SAUTHC1_SIGNED_HEADERS, $signedHeadersString) . ', ' . $this->createNameValuePair(self::SAUTHC1_SIGNATURE, $signatureHex); $requestHeaders[self::AUTHORIZATION_HEADER] = $authorizationHeader; $request->setHeaders($requestHeaders); }
private function applyDefaultRequestHeaders(Request $request) { $headers = $request->getHeaders(); $headers['Accept'] = 'application/json'; $userAgentBuilder = new UserAgentBuilder(); $headers['User-Agent'] = $userAgentBuilder->setOsName(php_uname('s'))->setOsVersion(php_uname('r'))->setPhpVersion(phpversion())->build(); if ($body = $request->getBody()) { $headers['Content-Type'] = 'application/json'; if (strpos($request->getResourceUrl(), '/oauth/token')) { $arr = json_decode($body); $arr = (array) $arr; ksort($arr); $body = http_build_query($arr); $request->setBody($body, strlen($body)); $headers['Content-Type'] = 'application/x-www-form-urlencoded'; $headers['Content-Length'] = $request->getContentLength(); } } $request->setHeaders($headers); }