我正在尝试为存储在Google Cloud Storage(GCS)上的对象生成一个签名URL。
为此,我正在尝试按照以下定义对Blob /对象进行签名:
GET
<expiration time>
/<bucket name>/<object/blob name>
我首先尝试了Google的serviceAccounts.signBlob API,如下页所述:
https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/signBlob
base64编码的字符串。
注意,如上面链接的页面上的API文档所述,我将要签名的Blob的base64表示形式传递给了API。
API的响应具有以下结构,其中包含signedBlob
键:
{
"keyId": "...",
"signedBlob": "..."
}
然后,我使用获得的签名Blob如下生成签名URL:
encoded_signedBlob = base64.b64encode(signedBlob)
signed_url = "https://storage.googleapis.com/{}/{}?" \
"GoogleAccessId={}&" \
"Expires={}&" \
"Signature={}".format(
bucket_name, blob_name,
service_account_email,
expiration,
encoded_signedBlob)
,当我将签名的URL粘贴到浏览器中以下载blob时,出现以下错误:
<Error>
<Code>SignatureDoesNotMatch</Code>
<Message>
The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.
</Message>
<StringToSign>GET <bucket name> <blob/object name></StringToSign>
</Error>
然后我尝试按以下方法在python中实现它,但仍然遇到相同的错误。
# -------------
# Part 1: obtain access token using the authorization flow discussed at:
# https://cloud.google.com/iam/docs/creating-short-lived-service-account-credentials
# -------------
client_service_account = "..."
access_token = build(
serviceName='iamcredentials',
version='v1',
http=http
).projects().serviceAccounts().generateAccessToken(
name="projects/{}/serviceAccounts/{}".format(
'-',
service_account_email),
body=body
).execute()["accessToken"]
credentials = AccessTokenCredentials(access_token, "MyAgent/1.0", None)
# -------------
# Part 2: sign the blob
# -------------
service = discovery.build('iam', 'v1', credentials=credentials)
name = 'projects/.../serviceAccounts/...'
encoded = base64.b64encode(blob)
sign_blob_request_body = {"bytesToSign": encoded}
request = service.projects().serviceAccounts().signBlob(name=name, body=sign_blob_request_body)
response = request.execute()
keyId = response["keyId"]
signedBlob = response["signature"]
# -------------
# Part 3: generate signed URL
# -------------
encoded_signedBlob = base64.b64encode(signedBlob)
signed_url = "https://storage.googleapis.com/{}/{}?" \
"GoogleAccessId={}&" \
"Expires={}&" \
"Signature={}".format(
bucket_name, blob_name,
service_account_email,
expiration,
encoded_signedBlob)
答案 0 :(得分:0)
您可以看一下使用client libraries的实现,可以尝试一下,请记住在您的requirements.txt文件中包含google-cloud-storage和代码中指定的服务帐户python示例