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