Warning: This page is about Google's older APIs, the Google Data APIs; it's relevant only to the APIs that are listed in the Google Data APIs directory, many of which have been replaced with newer APIs. For information about a specific new API, see the new API's documentation. For information about authorizing requests with a newer API, see Google Accounts Authentication and Authorization.
This document describes how to use the Google Data API client libraries to connect to Google's AuthSub Authentication for Web Applications.
The AuthSub interface allows a web-based application to access a Google service on behalf of a user. To maintain a high level of security, the AuthSub interface enables the application to get an authentication token without ever handling the user's account login information.
The Google Data API client libraries provide methods to help you use AuthSub in your web application. Specifically, there are methods for constructing the request URL, acquiring a single-use authentication token, exchanging the single-use token for a session token, and signing the request.
Note: The JavaScript client library has its own flavor of AuthSub, called AuthSubJS. For information on how to use AuthSubJS in your JavaScript applications, see Using "AuthSub" Authentication with the JavaScript Client Library.
Audience
This document is intended for programmers who want their web-based applications to access Google services on behalf of users, using the Google Data APIs client libraries.
This document assumes that you are familiar with the AuthSub interface and the general process for incorporating AuthSub into your web application. For a complete description of AuthSub's protocol, see AuthSub Authentication for Web Applications.
Using AuthSub and Google Data APIs without the client libraries
If you want your web application client to interact with a Google Data service using AuthSub as an authentication system, then everything you really need to know is in AuthSub Authentication for Web Applications. You don't need to use the Google Data APIs client libraries if you don't want to.
Here's an outline of how your application might authenticate a user using AuthSub:
Your application constructs the appropriate AuthSub URL and then sends the user to that URL so they can log in; the AuthSub system sends the user back to the URL on your site that you specified, and returns a one-time-use token; your application optionally exchanges that token for a session token; then your application sends the token in the Authorization header with each request that the application sends to the service.
The Google Data APIs client libraries simplify this authorization process by handling various details for you. This document explains how.
Working with AuthSub and the Google Data APIs: client library examples
This section shows an example of using the Google Data APIs client library methods to follow the steps outlined in the "Working With AuthSub" section of the AuthSub documentation.
In this example, we're integrating the AuthSub interface into a web application that interacts with Google Calendar (although you don't need to know anything about Google Calendar to follow the example). The example assumes the web application is hosted at example.com
.
Decide what type of token to use (session=0
or session=1
)
You can choose to use single-use tokens (session=0
) or session tokens (session=1
).
This document will use session tokens, as they are more useful in applications that will make multiple API requests.
As discussed in the AuthSub documentation, if you decide to use session tokens in your web application, you'll need to manage
token storage yourself. This document does not cover token management. Also note that tokens requested with session=0
can't be later exchanged (upgraded) to a long-lived session token.
Decide whether to register your web application (secure=0
or secure=1
)
AuthSub can be used in three different modes, unregistered, registered, and registered with enchanced security. The remainder of this document will refer to the last option as secure AuthSub. Though unregistered/registered mode is simpler to set up than secure AuthSub, Google encourages you to use secure tokens for their enchanced security.
How to register
Choosing Registration for Web-Based Applications gives your application the following benefits:
- A higher level of security.
- Being trusted by Google (no warning is displayed to the user on the Google Authorization page).
Registered + Secure AuthSub
If you decide on secure AuthSub, you'll need to create a self-signing RSA private key and public certificate pair in addition to registering your web application. See Generating keys and certificates for use with registered mode (below) for examples of creating X.509 certificates.
Determine the scope of your data access
Each Google service defines a scope
value which determines (and possibly narrows) a token's access to the user's data.
See the FAQ for the list of available scope
values.
Since we decided to interact with the Google Calendar API, the scope
should be
http://www.google.com/calendar/feeds/
.
Note: Always set the scope value to the broadest URL possible unless you have need for a finer restriction.
For example, a narrower scope like scope=http://www.google.com/calendar/feeds/default/allcalendars/full
will restrict the token's
access to just the allcalendars/full feed. Using scope=http://www.google.com/calendar/feeds/
will allow access to all of
Calendar's feeds: http://www.google.com/calendar/feeds/*.
Multi-scoped tokens
To create tokens that access multiple Google Data APIs, seperate each scope with a url-encoded space. The example below creates a token which will have access to both a user's Google Contacts and Google Calendar data.
scope=http://www.google.com/calendar/feeds/%20http://www.google.com/m8/feeds/
Request a single-use authentication token
To acquire an AuthSub token for a given user and a given service, your application must redirect the user to the AuthSubRequest
URL, which prompts them to log into their Google account.
(For more information on the AuthSubRequest
URL, see the full AuthSub Authentication for Web Applications.)
To construct the AuthSubRequest
URL in your application, use the following for each client library:
Java
import com.google.gdata.client.*; String nextUrl = "http://www.example.com/RetrieveToken.jsp"; String scope = "http://www.google.com/calendar/feeds/"; boolean secure = false; // set secure=true to request secure AuthSub tokens boolean session = true; String authSubUrl = AuthSubUtil.getRequestUrl(nextUrl, scope, secure, session);
If you want to authenticate users on your G Suite domain:
import com.google.gdata.client.*; String hostedDomain = "example.com"; String nextUrl = "http://www.example.com/RetrieveToken.jsp"; String scope = "http://www.google.com/calendar/feeds/"; boolean secure = false; // set secure=true to request AuthSub tokens boolean session = true; String authSubUrl = AuthSubUtil.getRequestUrl(hostedDomain, nextUrl, scope, secure, session);
.NET
using Google.GData.Client; String nextUrl = "http://www.example.com/RetrieveToken.aspx"; String scope = "http://www.google.com/calendar/feeds/"; bool secure = false; // set secure=true to request secure AuthSub tokens bool session = true; String authSubUrl = AuthSubUtil.getRequestUrl(nextUrl, scope, secure, session);
If you want to authenticate users on your G Suite domain:
using Google.GData.Client; String hostedDomain = "example.com"; String nextUrl = "http://www.example.com/RetrieveToken.aspx"; String scope = "http://www.google.com/calendar/feeds/"; bool secure = false; // set secure=true to request secure AuthSub tokens bool session = true; String authSubUrl = AuthSubUtil.getRequestUrl(hostedDomain, nextUrl, scope, secure, session);
PHP
require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata_AuthSub'); $nextUrl = 'http://www.example.com/RetrieveToken.php'; $scope = 'http://www.google.com/calendar/feeds/'; $secure = 0; // set $secure=1 to request secure AuthSub tokens $session = 1; $authSubUrl = Zend_Gdata_AuthSub::getAuthSubTokenUri($nextUrl, $scope, $secure, $session);
If you want to authenticate users on your G Suite domain:
require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata_AuthSub'); $hostedDomain = 'example.com'; $nextUrl = 'http://www.example.com/RetrieveToken.php'; $scope = 'http://www.google.com/calendar/feeds/'; $secure = 0; // set $secure=1 to request secure AuthSub tokens $session = 1; $authSubUrl = Zend_Gdata_AuthSub::getAuthSubTokenUri($nextUrl, $scope, $secure, $session) . '&hd=' . $hostedDomain;
Python
import gdata.auth next = 'http://www.example.com/RetrieveToken.pyc' scope = 'http://www.google.com/calendar/feeds/' secure = False # set secure=True to request secure AuthSub tokens session = True auth_sub_url = gdata.auth.GenerateAuthSubRequestUrl(next, scope, secure=secure, session=session)
If you want to authenticate users on your G Suite domain:
import gdata.auth hosted_domain = 'example.com' next = 'http://www.example.com/RetrieveToken.pyc' scope = 'http://www.google.com/calendar/feeds/' secure = False # set secure=True to request secure AuthSub tokens session = True auth_sub_url = gdata.auth.GenerateAuthSubRequestUrl(next, scope, secure=secure, session=session, domain=hosted_domain)
After constructing the "next" URL, your application can use it in a variety of ways to send the user to the
AuthSubRequest
handler. The most common approach is to display a page that tells the user that they need to follow a link to
authorize your application to access their Google account; then attach the request URL to the link. For example, you could output the following
string in your web app:
String authorizationUrl = "<p>MyApp needs access to your Google Calendar account to read your Calendar feed. " + "To authorize MyApp to access your account, <a href=\"" + authSubUrl + "\">log in to your account</a>.</p>";
The user follows the link to the AuthSub page at Google, and logs in. The AuthSub system then redirects the user back to your application, using the "next" URL you provided.
Extract the single-use token
When Google redirects back to your application, the token is appended to the "next" URL as a query parameter. In the case of the examples
above, after the user logs in, Google redirects to a URL like http://www.example.com/RetrieveToken?token=DQAADKEDE
.
Your application should extract the token value from its URL query parameter.
If your application set an authentication cookie in the user's browser before sending them to the AuthSub system, then when Google redirects back to the "next" URL, your application can read the authentication cookie to recognize which user has arrived at that URL. You can use such a cookie to associate a user ID in your application with the AuthSub token retrieved from Google.
The client libraries provide convenience methods for extracting the single-use token:
Java
String singleUseToken = AuthSubUtil.getTokenFromReply(httpServletRequest.getQueryString());
.NET
String singleUseToken = Request.QueryString["token"]; // or String singleUseToken = AuthSubUtil.getTokenFromReply(new Uri(Request.QueryString));
PHP
$singleUseToken = $_GET['token'];
Python
current_url = 'http://' + req.hostname + req.unparsed_uri # Unlike the other calls, extract_auth_sub_token_from_url() will create anAuthSubToken
orSecureAuthSubToken
object. # Use str(single_use_token) to return the token's string value. single_use_token = gdata.auth.extract_auth_sub_token_from_url(current_url)
If you are using secure AuthSub, be sure to set your RSA private key so a SecureAuthSubToken
is created:
f = open('/path/to/yourRSAPrivateKey.pem') rsa_key = f.read() f.close() current_url = 'http://' + req.hostname + req.unparsed_uri # Unlike the other calls, extract_auth_sub_token_from_url() will create anAuthSubToken
orSecureAuthSubToken
object. # Use str(single_use_token) to return the token's string value. single_use_token = gdata.auth.extract_auth_sub_token_from_url(current_url, rsa_key=rsa_key)
Request a session token
The token you retrieve from the URL is always a single-use token. The next step is to upgrade that token for a long-lived session token using the AuthSubSessionToken
URL, as described
in the full AuthSub Authentication for Web Applications documentation. If you are using secure AuthSub, you'll need to set your RSA private key before
making the exchange. Here are some examples using each of the client libraries:
Java
import com.google.gdata.client.*; import com.google.gdata.client.calendar.*; String sessionToken = AuthSubUtil.exchangeForSessionToken(singleUseToken, null); CalendarService calendarService = new CalendarService("google-ExampleApp-v1.0"); calendarService.setAuthSubToken(sessionToken, null); // ready to interact with Calendar feeds
For secure AuthSub, pass your RSA private key to exchangeForSessionToken
instead of pasing null
:
import com.google.gdata.client.*; import com.google.gdata.client.calendar.*; java.security.PrivateKey privateKey = AuthSubUtil.getPrivateKeyFromKeystore("AuthSubExample.jks", "privKeyPa$$word", "AuthSubExample", "privKeyPa$$word"); String sessionToken = AuthSubUtil.exchangeForSessionToken(singleUseToken, privateKey); CalendarService calendarService = new CalendarService("google-ExampleApp-v1.0"); calendarService.setAuthSubToken(sessionToken, privateKey); // ready to interact with Calendar feeds
.NET
using Google.GData.Client; using Google.GData.Calendar; String sessionToken = AuthSubUtil.exchangeForSessionToken(singleUseToken, null).ToString(); GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("cl", "google-ExampleApp-v1.0"); authFactory.Token = (String) sessionToken; CalendarService calendarService = new CalendarService(authFactory.ApplicationName); calendarService.RequestFactory = authFactory; // ready to interact with Calendar feeds
For secure AuthSub, pass your RSA private key to exchangeForSessionToken
instead of pasing null
:
using Google.GData.Client; using Google.GData.Calendar; protected AsymmetricAlgorithm getRsaKey() { X509Certificate2 cert = new X509Certificate2("C:/MyAspSite/test_cert.pfx", "privKeyPa$$word"); RSACryptoServiceProvider privateKey = cert.PrivateKey as RSACryptoServiceProvider; return privateKey; } AsymmetricAlgorithm rsaKey = getRsaKey(); String sessionToken = AuthSubUtil.exchangeForSessionToken(singleUseToken, rsaKey).ToString(); GAuthSubRequestFactory authFactory = new GAuthSubRequestFactory("cl", "google-ExampleApp-v1.0"); authFactory.Token = (String) sessionToken; authFactory.PrivateKey = rsaKey; CalendarService calendarService = new CalendarService(authFactory.ApplicationName); calendarService.RequestFactory = authFactory; // ready to interact with Calendar feeds
PHP
require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata_AuthSub'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); $sessionToken = Zend_Gdata_AuthSub::getAuthSubSessionToken($singleUseToken); // Create a Calendar service object and set the session token for subsequent requests $calendarService = new Zend_Gdata_Calendar(null, 'google-ExampleApp-v1.0'); $calendarService->setAuthSubToken($sessionToken); // ready to interact with Calendar feeds
For secure AuthSub, the exchange requires you to first setup a Zend_Gdata_HttpClient
and set your RSA private key
using setAuthSubPrivateKeyFile()
:
require_once 'Zend/Loader.php'; Zend_Loader::loadClass('Zend_Gdata_AuthSub'); Zend_Loader::loadClass('Zend_Gdata_Calendar'); $client = new Zend_Gdata_HttpClient(); $client->setAuthSubPrivateKeyFile('/path/to/myrsakey.pem', null, true); $sessionToken = Zend_Gdata_AuthSub::getAuthSubSessionToken($singleUseToken, $client); $calendarService = new Zend_Gdata_Calendar($client, 'google-ExampleApp-v1.0'); $calendarService->setAuthSubToken($sessionToken); // ready to interact with Calendar feeds
Python
import gdata.calendar import gdata.calendar.service calendar_service = gdata.calendar.service.CalendarService() calendar_service.UpgradeToSessionToken(single_use_token) # calls gdata.service.SetAuthSubToken() for you # ready to interact with Calendar feeds
Note: The process is the same for secure AuthSub as long as you have used
gdata.auth.extract_auth_sub_token_from_url(url, rsa_key=rsa_key)
to extract the single-use token.
Note: When using secure AuthSub, your private key itself is not sent over the network. The client libraries send the unique signature generated by signing the request with your key, not the key itself.
Use the session token
You can use the session token to authenticate requests to the server by placing the token in the Authorization header, as described in the AuthSub documentation.
After you've set your session token, you can use the standard Google Data APIs client library calls to interact with the service, without having to think about the token. For details, see the client library documentation and the Google Data APIs developer guide for the service and language you're interacting with.
Retrieving information about a session token
If you want to test that your client and the server agree on the token's parameters, you can pass the token to the
AuthSubTokenInfo
handler, which returns a set of name-value pairs containing information about the token.
Java
Map<String, String> tokenInfo = AuthSubUtil.getTokenInfo(sessionToken, null);
If you're using secure AuthSub, pass in your RSA private key:
Map<String, String> tokenInfo = AuthSubUtil.getTokenInfo(sessionToken, privateKey);
.NET
Dictionary<String, String> tokenInfo = AuthSubUtil.GetTokenInfo(sessionToken, null);
If you're using secure AuthSub, pass in your RSA private key:
Dictionary<String, String> tokenInfo = AuthSubUtil.GetTokenInfo(sessionToken, privateKey);
PHP
$tokenInfo = Zend_Gdata_AuthSub::getAuthSubTokenInfo($sessionToken);
If you're using secure AuthSub, pass in your Zend_Gdata_HttpClient
so the request is signed with your RSA private key:
$tokenInfo = Zend_Gdata_AuthSub::getAuthSubTokenInfo($sessionToken, $client);
Python
token_info = calendar_service.AuthSubTokenInfo()
Revoke a session token
AuthSub session tokens don't expire; your client can store the session token for as long as needed.
Therefore, when your client is done using the session token, it can revoke the token using the AuthSubRevokeToken
handler, as described in the AuthSub documentation.
For example, if you want to manage tokens in a traditional session-like way, then your client can get a token at the beginning of a user's session and revoke it at the end of the user's session.
To revoke a token use the following in each client library:
Java
AuthSubUtil.revokeToken(sessionToken, null);
If you're using secure AuthSub, pass in your RSA private key:
AuthSubUtil.revokeToken(sessionToken, privateKey);
.NET
AuthSubUtil.revokeToken(sessionToken, null);
If you're using secure AuthSub, pass in your RSA private key:
AuthSubUtil.revokeToken(sessionToken, privateKey);
PHP
$wasRevoked = Zend_Gdata_AuthSub::AuthSubRevokeToken($sessionToken);
If you're using secure AuthSub, pass in your Zend_Gdata_HttpClient
so the request is signed with your RSA private key:
$wasRevoked = Zend_Gdata_AuthSub::AuthSubRevokeToken($sessionToken, $client);
Python
calendar_service.RevokeAuthSubToken()
Additional Resources and Samples
- AuthSub examples on the Google Data API Tips Blog
- Python client library AuthSub sample
- Java client library AuthSub sample
- Article: Using AuthSub with the .NET Client Library
- Article: Using "AuthSub" Authentication with the JavaScript Client Library
Generating a self-signing private key and public certificate for use with secure AuthSub
The private key is used to generate a signature, which must be included with each request. The public key embedded in the certificate is used by Google to verify the signature. The public key must be a 1024-bit RSA key encoded in an X.509 certificate in PEM format. The certificate should be sent to Google at time of registration.
The following sections provide examples of how to generate keys and certificates using two particular tools: the OpenSSL
utility and Java's keytool
utility.
These examples are not specific to the Google Data APIs; you can use the same utilities to generate keys for any purpose.
The examples assume that your company is named My_Company, and is located in Mountain View, California, US, with domain name example.com.
Generating keys using OpenSSL
To create a pair of RSA keys and the corresponding certificate, you could use the following command:
# Generate the RSA keys and certificate openssl req -x509 -nodes -days 365 -newkey rsa:1024 -sha1 -subj \ '/C=US/ST=CA/L=Mountain View/CN=www.example.com' -keyout \ myrsakey.pem -out /tmp/myrsacert.pem
Warning: Including the -nodes
parameter creates a private key without a password to protect it.
However, you should consider omitting this parameter for added security.
The -sha1
parameter specifies that the key will be used to generate SHA1 signatures.
The -subj
parameter specifies the identity of the application that the certificate represents.
The -keyout
parameter specifies the file that will contain the keys.
This file contains sensitive information and should be protected and not shared with anyone.
The -out
parameter specifies the file that will contain the certificate in PEM format
(which can be sent to Google while registering).
Generating keys for the .NET client
The .NET framework doesn't understand keys or certificates stored in the PEM format. Therefore, an additional step is needed once you have created the .pem file:
openssl pkcs12 -export -in test_cert.pem -inkey myrsacert.pem -out myrsacert.pfx -name "Testing Certificate"
This step generates a PFX file from your private key and certificate. This file can be imported into the .NET client library to digitally sign requests made to the Google Data APIs.
Generating keys for the Java client
The Java client accepts private keys in the PKCS#8 format. After generating a key/cert using the directions above, create a .pk8 file from your generated .pem file:
openssl pkcs8 -in myrsakey.pem -topk8 -nocrypt -out myrsakey.pk8
Alternatively, you can use the Java key store and the keytool utility to create a pair of RSA keys and the corresponding certificate. Use the following command:
# Generate the RSA keys and certificate keytool -genkey -v -alias Example -keystore ./Example.jks\ -keyalg RSA -sigalg SHA1withRSA\ -dname "CN=www.example.com, OU=Engineering, O=My_Company, L=Mountain View, ST=CA, C=US"\ -storepass changeme -keypass changeme
Warning: "changeme
" is not a good password; this is just an example.
The -dname
parameter specifies the identity of the application that the certificate represents. The -storepass
parameter specifies the password to protect the keystore. The -keypass
parameter specifies the password to protect the private key.
To write the certificate to a file that can be used in the ManageDomains tool, use the following command:
# Output the public certificate to a file keytool -export -rfc -keystore ./Example.jks -storepass changeme \ -alias Example -file mycert.pem