93 lines
3.1 KiB
Python
93 lines
3.1 KiB
Python
# Copyright 2014 Baidu, Inc.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file
|
|
# except in compliance with the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software distributed under the
|
|
# License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|
# either express or implied. See the License for the specific language governing permissions
|
|
# and limitations under the License.
|
|
|
|
"""
|
|
This module provides authentication functions for bce services.
|
|
"""
|
|
from __future__ import absolute_import
|
|
from builtins import str
|
|
from builtins import bytes
|
|
import hashlib
|
|
import hmac
|
|
import logging
|
|
|
|
from baidubce.http import http_headers
|
|
from baidubce import utils
|
|
from baidubce import compat
|
|
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
def _get_canonical_headers(headers, headers_to_sign=None):
|
|
headers = headers or {}
|
|
|
|
if headers_to_sign is None or len(headers_to_sign) == 0:
|
|
headers_to_sign = set([b"host",
|
|
b"content-md5",
|
|
b"content-length",
|
|
b"content-type"])
|
|
result = []
|
|
for k in headers:
|
|
k_lower = k.strip().lower()
|
|
value = utils.convert_to_standard_string(headers[k]).strip()
|
|
if k_lower.startswith(http_headers.BCE_PREFIX) \
|
|
or k_lower in headers_to_sign:
|
|
str_tmp = b"%s:%s" % (utils.normalize_string(k_lower), utils.normalize_string(value))
|
|
result.append(str_tmp)
|
|
result.sort()
|
|
return (b'\n').join(result)
|
|
|
|
|
|
def sign(credentials, http_method, path, headers, params,
|
|
timestamp=0, expiration_in_seconds=1800, headers_to_sign=None):
|
|
"""
|
|
Create the authorization
|
|
"""
|
|
|
|
_logger.debug('Sign params: %s %s %s %s %d %d %s' % (
|
|
http_method, path, headers, params, timestamp, expiration_in_seconds, headers_to_sign))
|
|
|
|
headers = headers or {}
|
|
params = params or {}
|
|
|
|
sign_key_info = b'bce-auth-v1/%s/%s/%d' % (
|
|
credentials.access_key_id,
|
|
utils.get_canonical_time(timestamp),
|
|
expiration_in_seconds)
|
|
sign_key = hmac.new(
|
|
credentials.secret_access_key,
|
|
sign_key_info,
|
|
hashlib.sha256).hexdigest()
|
|
|
|
canonical_uri = path
|
|
canonical_querystring = utils.get_canonical_querystring(params, True)
|
|
|
|
canonical_headers = _get_canonical_headers(headers, headers_to_sign)
|
|
string_to_sign = (b'\n').join([
|
|
http_method, canonical_uri,
|
|
canonical_querystring, canonical_headers
|
|
])
|
|
sign_result = hmac.new(compat.convert_to_bytes(sign_key), string_to_sign, hashlib.sha256).hexdigest()
|
|
# convert to bytes
|
|
sign_result = compat.convert_to_bytes(sign_result)
|
|
|
|
if headers_to_sign:
|
|
result = b'%s/%s/%s' % (sign_key_info, (b';').join(headers_to_sign), sign_result)
|
|
else:
|
|
result = b'%s//%s' % (sign_key_info, sign_result)
|
|
|
|
_logger.debug('sign_key=[%s] sign_string=[%d bytes][ %s ]' %
|
|
(sign_key, len(string_to_sign), string_to_sign))
|
|
_logger.debug('result=%s' % result)
|
|
return result
|