123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- <?php
- require_once(XASSET_PATH . 'auth/SignerInterface.php');
- require_once(XASSET_PATH . 'auth/SignOptions.php');
- require_once(XASSET_PATH . 'common/config/HttpHeaders.php');
- require_once(XASSET_PATH . 'auth/HttpUtils.php');
- require_once(XASSET_PATH . 'auth/DateUtils.php');
- /**
- * The V1 implementation of Signer with the BCE signing protocol.
- */
- class BceV1Signer implements SignerInterface
- {
- const BCE_AUTH_VERSION = "bce-auth-v1";
- // Default headers to sign with the BCE signing protocol.
- private static $defaultHeadersToSign;
- public static function __init()
- {
- BceV1Signer::$defaultHeadersToSign = array(
- strtolower(HttpHeaders::HOST),
- strtolower(HttpHeaders::CONTENT_LENGTH),
- strtolower(HttpHeaders::CONTENT_TYPE),
- strtolower(HttpHeaders::CONTENT_MD5),
- );
- }
- /**
- * Sign the given request with the given set of credentials. Modifies the passed-in request to apply the signature.
- *
- * @param $credentials array the credentials to sign the request with.
- * @param $httpMethod string
- * @param $path string
- * @param $headers array
- * @param $params array
- * @param $options array the options for signing.
- * @return string The signed authorization string.
- */
- public function sign(
- array $credentials,
- $httpMethod,
- $path,
- $headers,
- $params,
- $options = array()
- )
- {
- if (!isset($options[SignOptions::EXPIRATION_IN_SECONDS])) {
- $expirationInSeconds = SignOptions::DEFAULT_EXPIRATION_IN_SECONDS;
- } else {
- $expirationInSeconds = $options[SignOptions::EXPIRATION_IN_SECONDS];
- }
- // to compatible with ak/sk or accessKeyId/secretAccessKey
- if (isset($credentials['ak'])) {
- $accessKeyId = $credentials['ak'];
- }
- if (isset($credentials['sk'])) {
- $secretAccessKey = $credentials['sk'];
- }
- if (isset($credentials['accessKeyId'])) {
- $accessKeyId = $credentials['accessKeyId'];
- }
- if (isset($credentials['secretAccessKey'])) {
- $secretAccessKey = $credentials['secretAccessKey'];
- }
- if (isset($options[SignOptions::TIMESTAMP])) {
- $timestamp = $options[SignOptions::TIMESTAMP];
- } else {
- $timestamp = new \DateTime();
- }
- $timestamp->setTimezone(DateUtils::$UTC_TIMEZONE);
- $authString = BceV1Signer::BCE_AUTH_VERSION . '/' . $accessKeyId . '/'
- . DateUtils::formatAlternateIso8601Date(
- $timestamp
- ) . '/' . $expirationInSeconds;
- $signingKey = hash_hmac('sha256', $authString, $secretAccessKey);
- // Formatting the URL with signing protocol.
- $canonicalURI = BceV1Signer::getCanonicalURIPath($path);
- // Formatting the query string with signing protocol.
- $canonicalQueryString = HttpUtils::getCanonicalQueryString(
- $params,
- true
- );
- // Sorted the headers should be signed from the request.
- $headersToSignOption = null;
- if (isset($options[SignOptions::HEADERS_TO_SIGN])) {
- $headersToSignOption = $options[SignOptions::HEADERS_TO_SIGN];
- }
- $headersToSign = BceV1Signer::getHeadersToSign($headers, $headersToSignOption);
- // Formatting the headers from the request based on signing protocol.
- $canonicalHeader = BceV1Signer::getCanonicalHeaders($headersToSign);
- $headersToSign = array_keys($headersToSign);
- sort($headersToSign);
- $signedHeaders = '';
- if ($headersToSignOption !== null) {
- $signedHeaders = strtolower(
- trim(implode(";", $headersToSign))
- );
- }
- $canonicalRequest = "$httpMethod\n$canonicalURI\n" . "$canonicalQueryString\n$canonicalHeader";
- // Signing the canonical request using key with sha-256 algorithm.
- $signature = hash_hmac('sha256', $canonicalRequest, $signingKey);
- $authorizationHeader = "$authString/$signedHeaders/$signature";
- return $authorizationHeader;
- }
- /**
- * @param $path string
- * @return string
- */
- private static function getCanonicalURIPath($path)
- {
- if (empty($path)) {
- return '/';
- } else {
- if ($path[0] == '/') {
- return HttpUtils::urlEncodeExceptSlash($path);
- } else {
- return '/' . HttpUtils::urlEncodeExceptSlash($path);
- }
- }
- }
- /**
- * @param $headers array
- * @return string
- */
- private static function getCanonicalHeaders($headers)
- {
- if (count($headers) == 0) {
- return '';
- }
- $headerStrings = array();
- foreach ($headers as $k => $v) {
- if ($k === null) {
- continue;
- }
- if ($v === null) {
- $v = '';
- }
- $headerStrings[] = rawurlencode(
- strtolower(trim($k))
- ) . ':' . rawurlencode(trim($v));
- }
- sort($headerStrings);
- return implode("\n", $headerStrings);
- }
- /**
- * @param $headers array
- * @param $headersToSign array
- * @return array
- */
- private static function getHeadersToSign($headers, $headersToSign)
- {
- $ret = array();
- if ($headersToSign !== null) {
- $tmp = array();
- foreach ($headersToSign as $header) {
- $tmp[] = strtolower(trim($header));
- }
- $headersToSign = $tmp;
- }
- foreach ($headers as $k => $v) {
- if (trim((string)$v) !== '') {
- if ($headersToSign !== null) {
- if (in_array(strtolower(trim($k)), $headersToSign)) {
- $ret[$k] = $v;
- }
- } else {
- if (BceV1Signer::isDefaultHeaderToSign($k)
- ) {
- $ret[$k] = $v;
- }
- }
- }
- }
- return $ret;
- }
- /**
- * @param $header string
- * @return bool
- */
- private static function isDefaultHeaderToSign($header)
- {
- $header = strtolower(trim($header));
- if (in_array($header, BceV1Signer::$defaultHeadersToSign)) {
- return true;
- }
- $prefix = substr($header, 0, strlen(HttpHeaders::BCE_PREFIX));
- if ($prefix === HttpHeaders::BCE_PREFIX) {
- return true;
- } else {
- return false;
- }
- }
- }
- BceV1Signer::__init();
|