SignatureDoesNotMatch с API Google serviceAccounts.signBlob - PullRequest
0 голосов
/ 28 июня 2019

Я пытаюсь создать подписанный URL-адрес для объекта, хранящегося в Google Cloud Storage (GCS).

Попытка 1: попробуйте API с помощью API Explorer

. Для этого я пытаюсь подписать BLOB-объект / объект, как указано ниже:

GET


<expiration time>
/<bucket name>/<object/blob name>

IСначала попробовал Google serviceAccounts.signBlob API, как обсуждалось на следующей странице:

https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/signBlob

Строка в кодировке base64.

Обратите внимание, что, как упоминалось в документации API на указанной выше странице, я передаю API-представление в виде base64, которое я хочу подписать.

Ответ API имеет следующую структуру:содержит ключ signedBlob:

{
  "keyId": "...",
  "signedBlob": "..."
}

, затем я сгенерировал подписанный 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>

Попытка 2: попробуйте библиотеки Python

Затем я попытался реализовать его в 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)

1 Ответ

0 голосов
/ 02 июля 2019

Вы можете взглянуть на реализацию этого с помощью клиентских библиотек , вы можете попробовать, не забудьте включить google-cloud-storage в ваш файл require.txt и служебную учетную запись, как указано в примере кода для python

...