29

On Google App Engine (GAE) written in Python.

I am trying to issue an http post to cloud-speech-to-text api and using URI audio source (Google Cloud Storage Bucket Objects).

I am using the following headers;

Authorization: BASIC encoded_base64(username:password)

But I still keep getting an error response below:

{ "error": { "code": 403, "message": "Anonymous caller does not have storage.objects.get access to bucket_of_secrets/four_score_seven_years.flac.", "status": "PERMISSION_DENIED" } }

So I have a couple of questions;

  1. Does BASIC Authorization Header work in Google HTTP API?
  2. What username:password should I use? Is it my GCP account email and password? i.e. handsome_dude@gmail.com:deluded_fool

Where handsome_dude@gmail.com is the username and deluded_fool is the password.

I've tried setting the bucket objects to be public readable and of course the http call works... but I would rather avoid setting my bucket objects public readable.

Here's a sample Curl request:

curl -X POST 

https://speech.googleapis.com/v1/speech:longrunningrecognize?key=<secret_api_key> -d @sample.json -H "Content-Type: application/json, Authorization:  Basic base64encodedusername:password" 

Here's a snippet in my python code using urlfetch:

url_post = urlfetch.fetch(url=speech_to_text_url_post, payload=json.dumps(data_to_post), method=urlfetch.POST, headers={"Content-Type" : "application/json", "Authorization" : "Basic "+encoded_user_password})
nyedidikeke
  • 6,899
  • 7
  • 44
  • 59
James Ching
  • 456
  • 1
  • 5
  • 10
  • Note also that best practices would suggest that you now change your password, since you have sent it to a service in an unexpected way and it has potentially been written to that service's internal log files as a result. The possibility of compromise is negilgible but not technically zero. – Michael - sqlbot May 25 '19 at 20:36

4 Answers4

14

1.Does BASIC Authorization Header work in Google HTTP API?

No, It is not working on Google APIs. You need to attach OAuth2.0 accessToken to Authorization Header as bearer token like Authorization: Bearer ${yourAccessToken}.

I have 2 recommendations to develop some application running on gae.

  1. Use ClientLibrary to call Google APIs.
  2. You can use AppEngineDefaultCredential to call Google APIs. Do not forget to set permissions to your AppEngineDefaultServiceAccount (${projectId}@appspot.gserviceaccount.com) before issue your request. You can configure those permissions on IAM page in cloud console.

Also I recommend you to read this page about How to authenticate your api call.

takryo
  • 429
  • 4
  • 8
  • Thanks for the confirmation and the alternative solutions. Just a quick question, as this is my first time working on GAE. On your #2 solution. Does AppEngineDefaultCredential work on HTTP API requests or is that for ClientLibrary API calls? – James Ching May 25 '19 at 11:23
  • 2
    @JamesChing Works for both. The App Engine default service account provides the same type of credentials that the client libraries consume/generate. – John Hanley May 25 '19 at 15:01
7

If you want to grant public access, you can make data public.

https://cloud.google.com/storage/docs/access-control/making-data-public

But the best way is generate Signed Urls, this way you can grant limit time access to an object.

https://cloud.google.com/storage/docs/access-control/signed-urls

BlackVegetable
  • 12,594
  • 8
  • 50
  • 82
João Krabbe
  • 79
  • 1
  • 2
1

For me, the issue was using role "Storage Legacy Object Reader", that, for whatever reason, was suggested. Changing it to "Storage Object Viewer" solved the issue.

BoltKey
  • 1,994
  • 1
  • 14
  • 26
0

I landed here because I forgot to run

./google-cloud-sdk/bin/gcloud init

from the Installation Guide.

Jobeso
  • 653
  • 1
  • 9
  • 11