Use oauth2 service account to authenticate to Google API in python

leontp587

I've followed the directions in https://developers.google.com/accounts/docs/OAuth2ServiceAccount to use a service account to authenticate to the Google Cloud Storage API. I tried to send a JWT to google's authenticate servers in python, but got an error:

urllib2.HTTPError: HTTP Error 400: Bad Request

It looks like there's something wrong with the way I'm making, signing, or sending the JWT? The error wasn't specific so it could be any part of the process. Does anyone have any ideas?

import Crypto.PublicKey.RSA as RSA
import Crypto.Hash.SHA as SHA
import Crypto.Signature.PKCS1_v1_5 as PKCS1_v1_5
import base64
import json
import time
import urllib2
import urllib

# Settings
json_key_file = 'GooglePM-9f75ad112f87-service.json'

# Load the private key associated with the Google service account
with open(json_key_file) as json_file:
    json_data = json.load(json_file)
    key = RSA.importKey(json_data['private_key'])

# Create an PKCS1_v1_5 object
signer = PKCS1_v1_5.new(key)

# Encode the JWT header
header_b64 = base64.urlsafe_b64encode(json.dumps({'alg':'RS256','typ':'JWT'}))

# JWT claims
jwt = {
    'iss': json_data['client_email'],
    'scope': 'https://www.googleapis.com/auth/devstorage.read_write',
    'aud': 'https://accounts.google.com/o/oauth2/token',
    'exp': int(time.time())+3600,
    'iat': int(time.time())
    }
jwt_json = json.dumps(jwt)

# Encode the JWT claims
jwt_json_b64 = base64.urlsafe_b64encode(jwt_json)

# Sign the JWT header and claims
msg_hash = SHA.new(header_b64 + "." + jwt_json_b64)
signature_b64 = base64.urlsafe_b64encode(signer.sign(msg_hash))

# Make the complete message
jwt_complete = header_b64 + "." + jwt_json_b64 + "." + signature_b64

data = {'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer', 
    'assertion': jwt_complete}

f = urllib2.urlopen("https://accounts.google.com/o/oauth2/token", urllib.urlencode(data))

print f.read()

If I try to use curl to post to the server, I get the invalid grants error:

(venv)$ curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiAiUlMyNTYiLCAidHlwIjogIkpXVCJ9.eyJpc3MiOiAiMTM1MDY3NjIyMTk4LWVhbWUwZnFqdTNvamRoZ29zdDg2dnBpdTBsYW91NnZlQGRldmVsb3Blci5nc2VydmljZWFjY291bnQuY29tIiwgInNjb3BlIjogImh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvZGV2c3RvcmFnZS5yZWFkX3dyaXRlIiwgImF1ZCI6ICJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20vby9vYXV0aDIvdG9rZW4iLCAiZXhwIjogMTQwODY1MTU2OCwgImlhdCI6IDE0MDg2NDg1NTh9.HWC7h3QiOy7QsSuta4leq_Gjwmy9IdF-MUwflPhiohzAJ-Amykd56Ye4Y_Saf_sAc5STzOCmrSPzOTYvGXr6X_T_AmSTxXK2AJ2SpAiEUs2_Wp5h18xTUY3Y_hkKvSZLh5bRzeJ_0xRcmRIPE6tua0FHFwUDdnCIGdh4DGg6i4E%3D' https://accounts.google.com/o/oauth2/token
{
  "error" : "invalid_grant"
}
leontp587

Ok so there's a better way to do this! Google already has a python client API that handles some of the complexity. The following code works after installing google python client API: https://developers.google.com/api-client-library/python/guide/aaa_oauth

from oauth2client.client import SignedJwtAssertionCredentials
import json
import urllib
import urllib2

# Settings
json_key_file = 'GooglePM-9f75ad112f87-service.json'

# Load the private key associated with the Google service account
with open(json_key_file) as json_file:
    json_data = json.load(json_file)

# Get and sign JWT
credential = SignedJwtAssertionCredentials(json_data['client_email'], json_data['private_key'], 'https://www.googleapis.com/auth/devstorage.read_write')
jwt_complete = credential._generate_assertion()

# Get token from server
data = {'grant_type': 'urn:ietf:params:oauth:grant-type:jwt-bearer', 
    'assertion': jwt_complete}
f = urllib2.urlopen("https://accounts.google.com/o/oauth2/token", urllib.urlencode(data))

print f.read()

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

From Dev

How to authenticate with Google Email Settings API using service account oauth2 Python client?

From Dev

Move Google EmailSettings API python code from OAuth1 to OAuth2 service account

From Dev

Move Google EmailSettings API python code from OAuth1 to OAuth2 service account

From Dev

Use to Chrome Store Publishing API with OAuth2 Service Account

From Dev

Google API OAuth2, Service Account, "error" : "invalid_grant"

From Dev

How to use Service Account to authenticate with Google Cloud SQL Java

From Dev

How to use a service account with Google's python api and drive?

From Dev

Google OAuth2 Service Account HTTP/REST Authentication

From Dev

google oauth2 how to get private key for service account

From Dev

Use service account for OAuth2 authentication to gmail

From Dev

Use OAuth2 for authentication + compatibility with google.appengine.api.users service

From Dev

Use custom account instead of service account in Google API

From Java

Google Drive API Python Service Account Example

From Dev

Powershell for Google Cloud: Authenticate with a service account

From Dev

Google API OAuth 2.0 Service Account C# First time vs every day use

From Dev

Authenticate own Google account for Blogger API with Java

From Dev

Authenticate own Google account for Blogger API with Java

From Dev

How to NOT use OAuth2 with google API (adwords in particular)

From Dev

Google OAuth2 with Service Account - specifying the user email to act on behalf of

From Dev

google service account example returns "Error refreshing the OAuth2 token { “error” : “invalid_grant” }"

From Dev

Google OAuth2 with Service Account - specifying the user email to act on behalf of

From Dev

Use of google service account for DFP

From Dev

Google Calendar Python API with service account returning no results

From Dev

How to authenticate google APIs with different service account credentials?

From Dev

Authenticate as a service account from Android app for Google Cloud Storage

From Dev

Authenticate Chrome extension with non-Google API using Google account

From Dev

Google OAuth2 api

From Dev

How to Google OAuth2 to upload videos to 2 different YouTube account with a Python script

From Dev

Google API access using Service Account oauth2client.client.CryptoUnavailableError: No crypto library available

Related Related

  1. 1

    How to authenticate with Google Email Settings API using service account oauth2 Python client?

  2. 2

    Move Google EmailSettings API python code from OAuth1 to OAuth2 service account

  3. 3

    Move Google EmailSettings API python code from OAuth1 to OAuth2 service account

  4. 4

    Use to Chrome Store Publishing API with OAuth2 Service Account

  5. 5

    Google API OAuth2, Service Account, "error" : "invalid_grant"

  6. 6

    How to use Service Account to authenticate with Google Cloud SQL Java

  7. 7

    How to use a service account with Google's python api and drive?

  8. 8

    Google OAuth2 Service Account HTTP/REST Authentication

  9. 9

    google oauth2 how to get private key for service account

  10. 10

    Use service account for OAuth2 authentication to gmail

  11. 11

    Use OAuth2 for authentication + compatibility with google.appengine.api.users service

  12. 12

    Use custom account instead of service account in Google API

  13. 13

    Google Drive API Python Service Account Example

  14. 14

    Powershell for Google Cloud: Authenticate with a service account

  15. 15

    Google API OAuth 2.0 Service Account C# First time vs every day use

  16. 16

    Authenticate own Google account for Blogger API with Java

  17. 17

    Authenticate own Google account for Blogger API with Java

  18. 18

    How to NOT use OAuth2 with google API (adwords in particular)

  19. 19

    Google OAuth2 with Service Account - specifying the user email to act on behalf of

  20. 20

    google service account example returns "Error refreshing the OAuth2 token { “error” : “invalid_grant” }"

  21. 21

    Google OAuth2 with Service Account - specifying the user email to act on behalf of

  22. 22

    Use of google service account for DFP

  23. 23

    Google Calendar Python API with service account returning no results

  24. 24

    How to authenticate google APIs with different service account credentials?

  25. 25

    Authenticate as a service account from Android app for Google Cloud Storage

  26. 26

    Authenticate Chrome extension with non-Google API using Google account

  27. 27

    Google OAuth2 api

  28. 28

    How to Google OAuth2 to upload videos to 2 different YouTube account with a Python script

  29. 29

    Google API access using Service Account oauth2client.client.CryptoUnavailableError: No crypto library available

HotTag

Archive