Подписать блоб облачного хранилища Google с помощью токена доступа - PullRequest
0 голосов
/ 28 июня 2019

Цель: создание подписанного URL-адреса с использованием маркера доступа OAuth2.0

Все примеры и исходные коды, которые я найду для подписи блобов облачного хранилища Google, требуют файл учетных данных учетной записи службы (в частности, закрытый ключ).Например:

https://cloud.google.com/storage/docs/access-control/signing-urls-with-helpers#storage-signed-url-get-object-python

Однако, поскольку я следую за потоком авторизации, обсужденным здесь , у меня есть только токен доступа OAuth2.0 (и у меня нетфайл учетных данных и закрытый ключ учетной записи службы с доступом к корзине / объекту GCS).Поэтому мне было интересно, как я могу подписывать большие двоичные объекты с помощью маркеров доступа OAuth2.0.

Используемый код:

Я использую следующее для подписи больших двоичных объектов:


# First, get access token:
service_account = "<email address of a service account>"
access_token = build(
    serviceName='iamcredentials',
    version='v1',
    http=http
).projects().serviceAccounts().generateAccessToken(
    name="projects/{}/serviceAccounts/{}".format(
        "-",
        service_account),
    body=body
).execute()["accessToken"]

credentials = AccessTokenCredentials(access_token, "MyAgent/1.0", None)

# Second, use the access token to sign a blob
url = "https://iamcredentials.googleapis.com/v1/projects/-/serviceAccounts/{}:signBlob".format(service_account)
encoded = base64.b64encode(blob)
sign_blob_request_body = {"payload": encoded}

response = requests.post(url,
                         data=json.dumps(sign_blob_request_body),
                         headers={
                             'Content-Type': 'application/json',
                             'Authorization': 'Bearer {}'.format(credentials.access_token)})
signature = response.json()["signedBlob"]

# Third, use the signature to create signed URL:
encoded_signature = base64.b64encode(signature)
signed_url = "https://storage.googleapis.com/<BUCKET>/<OBJECT>?" \
             "GoogleAccessId={}&" \
             "Expires={}&" \
             "Signature={}".format(service_account, 
                                   expiration, 
                                   encoded_signature)

Получено сообщение об ошибке:

<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 1561832204 /<BUCKET>/<OBJECT></StringToSign>
</Error>

1 Ответ

0 голосов
/ 28 июня 2019

Если вы НЕ хотите использовать секретный ключ API, следуйте процедуре, описанной в этом примере , в которой используется API iamcredentials.signBlob () для удаленной подписи URL-адреса для службыучетная запись без необходимости распространения секретного ключа API.

Строка подписи (которая должна быть подписана) имеет следующий формат:

signature_string = ('{verb}\n'
                    '{content_md5}\n'
                    '{content_type}\n'
                    '{expiration}\n'
                    '{resource}')
...