Developers
Keys to the Kingdom:
OAuth in Google Cloud Platform
Ben Sittler
Software Engineer�bsittler@google.com
What are we covering today?
Let's make an API call
All I want to do is make an API call!
GET /bigquery/v2/projects/1234/datasets HTTP/1.1�Host: www.googleapis.com�Authorization: Bearer yaXXXXXXXXXX
What is a token?
How do I get one?
Configuring the project
Accessing data owned by my application
Project
Enable the service
Create a service account
Branding Information screen
Select "Service Account"
Download key
Take note of the email address
Let's get an access token
Create an assertion
� yyyyyyy@developer.gserviceaccount.com� https://www.googleapis.com/auth/bigquery�
Create an assertion
import time��now = long(time.time())
� {� "iss": "yyyyyyy@developer.gserviceaccount.com",� "scope": "https://www.googleapis.com/auth/bigquery",� "aud": "https://accounts.google.com/o/oauth2/token",� "exp": now + (60 * 60), "iat": now� }
Create an assertion
import time, json, base64��now = long(time.time())�assertion_input = "%s.%s" % (� base64.urlsafe_b64encode(
json.dumps({"alg": "RS256", "typ": "JWT"}).encode("UTF-8")
).rstrip("="),� base64.urlsafe_b64encode(json.dumps({� "iss": "yyyyyyy@developer.gserviceaccount.com",� "scope": "https://www.googleapis.com/auth/bigquery",� "aud": "https://accounts.google.com/o/oauth2/token",� "exp": now + (60 * 60), "iat": now� }).encode("UTF-8")).rstrip("="))
Sign it - and swap it
� � xxxxxxxx-privatekey.p12� notasecret
Sign it - and swap it
import urllib� from OpenSSL import crypto��
urllib.urlencode({
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",� "assertion": "%s.%s" % (assertion_input,� base64.urlsafe_b64encode(crypto.sign(crypto.load_pkcs12(� file("xxxxxxxx-privatekey.p12", "rb").read(),� "notasecret").get_privatekey(), assertion_input, "sha256")).rstrip("="))� })
Sign it - and swap it
import urllib2, urllib� from OpenSSL import crypto�� access_token = json.loads(urllib2.urlopen("https://accounts.google.com/o/oauth2/token",
urllib.urlencode({
"grant_type": "urn:ietf:params:oauth:grant-type:jwt-bearer",� "assertion": "%s.%s" % (assertion_input,� base64.urlsafe_b64encode(crypto.sign(crypto.load_pkcs12(� file("xxxxxxxx-privatekey.p12", "rb").read(),� "notasecret").get_privatekey(), assertion_input, "sha256")).rstrip("="))� })).read())["access_token"]
Result
{� "access_token" : "yaXXXXXXXXXXXXXXXXXXXXXXXX",� "token_type" : "Bearer",� "expires_in" : 3600�}
Try using it
print urllib2.urlopen(urllib2.Request(� "https://www.googleapis.com/bigquery/v2/projects/%s/datasets"
% "my-test-project-id",� headers={'Authorization': 'Bearer %s' % access_token}�)).read()
Try using it
print urllib2.urlopen(urllib2.Request(� "https://www.googleapis.com/bigquery/v2/projects/%s/datasets"
% "my-test-project-id",� headers={'Authorization': 'Bearer %s' % access_token}�)).read()
Result:
{� "kind": "bigquery#datasetList",� "etag": "..."�}
Using Google Client libraries
� yyyyyyyyyyy@developer.gserviceaccount.com � xxxxxxxxxxx-privatekey.p12� https://www.googleapis.com/auth/bigquery�
Using Google Client libraries
import httplib2�from oauth2client.client import SignedJwtAssertionCredentials��http = SignedJwtAssertionCredentials(� "yyyyyyyyyyy@developer.gserviceaccount.com",� file("xxxxxxxxxxx-privatekey.p12", "rb").read(),� scope="https://www.googleapis.com/auth/bigquery"�).authorize(httplib2.Http())
Use authorized HTTP object directly
print http.request("https://www.googleapis.com/bigquery/v2/projects/%s/datasets"
% "my-test-project-id")[1]
Use authorized HTTP object directly
print http.request("https://www.googleapis.com/bigquery/v2/projects/%s/datasets"
% "my-test-project-id")[1]
Result:
{� "kind": "bigquery#datasetList",� "etag": "..."�}
Or the full client library stack
from apiclient.discovery import build��service = build('bigquery', 'v2')�print service.datasets().list(projectId="my-test-project-id").execute(http)
Or the full client library stack
from apiclient.discovery import build��service = build('bigquery', 'v2')�print service.datasets().list(projectId="my-test-project-id").execute(http)
Result:
{� "kind": "bigquery#datasetList",� "etag": "..."�}
Google hosted environments
Google hosted environments?
Use built-in identity in Google App Engine
# Built-in:�
https://www.googleapis.com/auth/bigquery��
Use built-in identity in Google App Engine
# Built-in:�from google.appengine.api import app_identity��access_token, ttl = app_identity.get_access_token(� "https://www.googleapis.com/auth/bigquery")��
Use built-in identity in Google App Engine
# Built-in:�from google.appengine.api import app_identity��access_token, ttl = app_identity.get_access_token(� "https://www.googleapis.com/auth/bigquery")��# With client library:�
https://www.googleapis.com/auth/bigquery
Use built-in identity in Google App Engine
# Built-in:�from google.appengine.api import app_identity��access_token, ttl = app_identity.get_access_token(� "https://www.googleapis.com/auth/bigquery")��# With client library:�from oauth2client.appengine import AppAssertionCredentials��http = AppAssertionCredentials(� "https://www.googleapis.com/auth/bigquery").authorize(httplib2.Http())
Use built-in identity in Google Compute Engine
# When starting your VM - authorize the VM to use the scope you need:�gcutil --project=my-test-project-id addinstance foobar \
--service_account_scopes=https://www.googleapis.com/auth/bigquery��
Use built-in identity in Google Compute Engine
# When starting your VM - authorize the VM to use the scope you need:�gcutil --project=my-test-project-id addinstance foobar \
--service_account_scopes=https://www.googleapis.com/auth/bigquery��# Inside the VM:�curl "http://metadata/computeMetadata/v1/instance/service-accounts/default/token" -H “Metadata-Flavor: Google”
Use built-in identity in Google Compute Engine
# When starting your VM - authorize the VM to use the scope you need:�gcutil --project=my-test-project-id addinstance foobar \
--service_account_scopes=https://www.googleapis.com/auth/bigquery��# Inside the VM:�curl "http://metadata/computeMetadata/v1/instance/service-accounts/default/token" -H “Metadata-Flavor: Google”
# Result:
{� "access_token" : "yaXXXXXXXXXXXXXXXXXXXXXXXX",� "token_type" : "Bearer",� "expires_in" : 3600�}
Use client library on Google Compute Engine
https://www.googleapis.com/auth/bigquery
Use client library on Google Compute Engine
from oauth2client.gce import AppAssertionCredentials��http = AppAssertionCredentials(� "https://www.googleapis.com/auth/bigquery").authorize(httplib2.Http())
Authentication - summary
What is a token?
Authorization is based on the user
Billing/quota based on client
Summary
Thank You!
Adam Eijdenberg - eijdenberg@google.com
Ben Sittler - bsittler@google.com
Google Cloud Platform Resources
cloud.google.com - get started today
developers.google.com - docs and developer guidance
cloud.google.com/newsletter - stay up to date
googlecloudplatform.blogspot.com - our blog
https://developers.google.com/api-client-library/ - client libraries
https://developers.google.com/accounts/docs/OAuth2ServiceAccount - protocol details
Get questions answered on StackOverflow (google-oauth)
Developers