AuthSub в клиентских библиотеках протокола данных Google

Предупреждение . Эта страница посвящена старым API Google, API данных Google; это относится только к API, которые перечислены в каталоге API данных Google , многие из которых были заменены более новыми API. Для получения информации о конкретном новом API см. документацию по новому API. Информацию об авторизации запросов с помощью более нового API см. в разделе Аутентификация и авторизация учетных записей Google .

В этом документе описывается, как использовать клиентские библиотеки Google Data API для подключения к Google AuthSub Authentication for Web Applications .

Интерфейс AuthSub позволяет веб-приложению получать доступ к службе Google от имени пользователя. Для поддержания высокого уровня безопасности интерфейс AuthSub позволяет приложению получать токен аутентификации без обработки данных для входа в учетную запись пользователя.

Клиентские библиотеки Google Data API предоставляют методы, помогающие использовать AuthSub в веб-приложении. В частности, существуют методы создания URL-адреса запроса, получения одноразового токена аутентификации, обмена одноразового токена на токен сеанса и подписания запроса.

Примечание . Клиентская библиотека JavaScript имеет собственный вариант AuthSub, который называется AuthSubJS. Информацию о том, как использовать AuthSubJS в ваших приложениях JavaScript, см. в разделе Использование аутентификации «AuthSub» с клиентской библиотекой JavaScript .

Аудитория

Этот документ предназначен для программистов, которые хотят, чтобы их веб-приложения имели доступ к службам Google от имени пользователей, используя клиентские библиотеки Google Data API.

В этом документе предполагается, что вы знакомы с интерфейсом AuthSub и общим процессом включения AuthSub в ваше веб-приложение. Полное описание протокола AuthSub см. в разделе Аутентификация AuthSub для веб-приложений .

Использование AuthSub и API данных Google без клиентских библиотек

Если вы хотите, чтобы ваш клиент веб-приложения взаимодействовал со службой данных Google, используя AuthSub в качестве системы аутентификации, то все, что вам действительно нужно знать, находится в AuthSub Authentication for Web Applications . Вам не нужно использовать клиентские библиотеки API данных Google, если вы этого не хотите.

Вот схема того, как ваше приложение может аутентифицировать пользователя с помощью AuthSub:

Ваше приложение создает соответствующий URL-адрес AuthSub, а затем отправляет пользователя на этот URL-адрес, чтобы он мог войти в систему; система AuthSub отправляет пользователя обратно на указанный вами URL-адрес вашего сайта и возвращает одноразовый токен; ваше приложение может обменять этот токен на токен сеанса; затем ваше приложение отправляет токен в заголовке авторизации с каждым запросом, который приложение отправляет службе.

Клиентские библиотеки API данных Google упрощают этот процесс авторизации, обрабатывая для вас различные детали. В этом документе объясняется, как.

Работа с AuthSub и API данных Google: примеры клиентских библиотек

В этом разделе показан пример использования методов клиентской библиотеки API данных Google для выполнения действий, описанных в разделе " Работа с AuthSub " документации AuthSub.

В этом примере мы интегрируем интерфейс AuthSub в веб-приложение, которое взаимодействует с Календарем Google (хотя вам не нужно ничего знать о Календаре Google, чтобы следовать примеру). В примере предполагается, что веб-приложение размещено на example.com .

Решите, какой тип токена использовать ( session=0 или session=1 )

Вы можете использовать одноразовые токены ( session=0 ) или токены сеанса ( session=1 ). В этом документе будут использоваться токены сеанса, поскольку они более полезны в приложениях, которые будут выполнять несколько запросов API. Как обсуждалось в документации AuthSub, если вы решите использовать токены сеанса в своем веб-приложении, вам нужно будет самостоятельно управлять хранилищем токенов. Этот документ не распространяется на управление токенами. Также обратите внимание, что токены, запрошенные с session=0 , нельзя впоследствии обменять (обновить) на долгоживущий токен сеанса.

Решите, регистрировать ли ваше веб-приложение ( secure=0 или secure=1 ).

AuthSub можно использовать в трех разных режимах: незарегистрированный , зарегистрированный и зарегистрированный с повышенной безопасностью . В оставшейся части этого документа последний вариант будет называться безопасным AuthSub. Хотя незарегистрированный/зарегистрированный режим проще в настройке, чем безопасный AuthSub, Google рекомендует вам использовать безопасные токены для их повышенной безопасности.

Как зарегистрироваться

Выбор регистрации для веб-приложений дает вашему приложению следующие преимущества:

  1. Более высокий уровень безопасности.
  2. Доверие со стороны Google (на странице авторизации Google пользователю не отображается предупреждение).

Зарегистрировано + безопасный AuthSub

Если вы выберете безопасный AuthSub, вам потребуется создать пару самоподписывающего закрытого ключа RSA и открытого сертификата в дополнение к регистрации вашего веб-приложения. См. Генерация ключей и сертификатов для использования с зарегистрированным режимом (ниже) для примеров создания сертификатов X.509.

Определите область вашего доступа к данным

Каждая служба Google определяет значение scope , которое определяет (и, возможно, сужает) доступ токена к данным пользователя. Список доступных значений scope см. в разделе часто задаваемых вопросов .

Поскольку мы решили взаимодействовать с API Календаря Google, scope должна быть http://www.google.com/calendar/feeds/ .

Примечание . Всегда устанавливайте значение области действия на максимально широкий URL-адрес, если только вам не требуется более тонкое ограничение. Например, более узкая область действия, такая как scope=http://www.google.com/calendar/feeds/default/allcalendars/full ограничит доступ токена только к фиду allcalendars/full. Использование scope=http://www.google.com/calendar/feeds/ позволит получить доступ ко всем каналам Календаря: http://www.google.com/calendar/feeds/* .

Токены с несколькими областями

Чтобы создать токены для доступа к нескольким API данных Google, разделите каждую область пробелом в кодировке URL. В приведенном ниже примере создается токен, который будет иметь доступ как к контактам Google, так и к данным Календаря Google.

scope=http://www.google.com/calendar/feeds/%20http://www.google.com/m8/feeds/

Запрос одноразового токена аутентификации

Чтобы получить токен AuthSub для данного пользователя и данной службы, ваше приложение должно перенаправить пользователя на URL-адрес AuthSubRequest , который предложит ему войти в свою учетную запись Google. (Дополнительную информацию об URL-адресе AuthSubRequest см. в полной версии AuthSub Authentication for Web Applications .)

Чтобы создать URL-адрес AuthSubRequest в своем приложении, используйте для каждой клиентской библиотеки следующее:

Джава

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);

Если вы хотите аутентифицировать пользователей в вашем домене G Suite:

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);

.СЕТЬ

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);

Если вы хотите аутентифицировать пользователей в вашем домене G Suite:

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);

Если вы хотите аутентифицировать пользователей в вашем домене G Suite:

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;

питон

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)

Если вы хотите аутентифицировать пользователей в вашем домене G Suite:

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)

После создания «следующего» URL-адреса ваше приложение может использовать его различными способами для отправки пользователя обработчику AuthSubRequest . Самый распространенный подход — отобразить страницу, которая сообщает пользователю, что ему нужно перейти по ссылке, чтобы авторизовать ваше приложение для доступа к его учетной записи Google; затем прикрепите URL-адрес запроса к ссылке. Например, вы можете вывести следующую строку в своем веб-приложении:

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>";

Пользователь переходит по ссылке на страницу AuthSub в Google и входит в систему. Затем система AuthSub перенаправляет пользователя обратно в ваше приложение, используя указанный вами «следующий» URL-адрес.

Извлеките одноразовый токен

Когда Google перенаправляет обратно в ваше приложение, токен добавляется к «следующему» URL-адресу в качестве параметра запроса. В приведенных выше примерах после входа пользователя в систему Google перенаправляет его на URL-адрес вида http://www.example.com/RetrieveToken?token=DQAADKEDE . Ваше приложение должно извлекать значение маркера из параметра запроса URL.

Если ваше приложение установило файл cookie аутентификации в браузере пользователя перед отправкой их в систему AuthSub, то, когда Google перенаправляет обратно на «следующий» URL-адрес, ваше приложение может прочитать файл cookie аутентификации, чтобы распознать, какой пользователь прибыл на этот URL-адрес. Вы можете использовать такой файл cookie, чтобы связать идентификатор пользователя в вашем приложении с токеном AuthSub, полученным от Google.

Клиентские библиотеки предоставляют удобные методы для извлечения одноразового токена:

Джава

String singleUseToken = AuthSubUtil.getTokenFromReply(httpServletRequest.getQueryString());

.СЕТЬ

String singleUseToken = Request.QueryString["token"];
// or
String singleUseToken = AuthSubUtil.getTokenFromReply(new Uri(Request.QueryString));

PHP

$singleUseToken = $_GET['token'];

питон

current_url = 'http://' + req.hostname + req.unparsed_uri
# Unlike the other calls, extract_auth_sub_token_from_url() will create an AuthSubToken or SecureAuthSubToken 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)

Если вы используете защищенный AuthSub, обязательно установите закрытый ключ RSA, чтобы был создан SecureAuthSubToken :

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 an AuthSubToken or SecureAuthSubToken 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)

Запросить токен сеанса

Токен, который вы извлекаете из URL-адреса, всегда является одноразовым токеном. Следующим шагом является обновление этого токена для долговременного токена сеанса с использованием URL-адреса AuthSubSessionToken , как описано в полной документации AuthSub Authentication for Web Applications . Если вы используете безопасный AuthSub, вам необходимо установить закрытый ключ RSA перед обменом. Вот несколько примеров использования каждой из клиентских библиотек:

Джава

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

Для безопасного AuthSub передайте свой закрытый ключ RSA в exchangeForSessionToken вместо 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

.СЕТЬ

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

Для безопасного AuthSub передайте свой закрытый ключ RSA в exchangeForSessionToken вместо 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

Для безопасного AuthSub обмен требует, чтобы вы сначала установили Zend_Gdata_HttpClient и установили свой закрытый ключ RSA, используя 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

питон

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

Примечание . Процесс такой же для защищенного AuthSub, если вы использовали gdata.auth. extract_auth_sub_token_from_url (url, rsa_key=rsa_key) для извлечения одноразового токена.

Примечание . При использовании безопасного AuthSub ваш закрытый ключ не отправляется по сети. Клиентские библиотеки отправляют уникальную подпись, сгенерированную путем подписания запроса вашим ключом, а не самим ключом.

Использовать токен сеанса

Вы можете использовать токен сеанса для проверки подлинности запросов к серверу, поместив токен в заголовок авторизации, как описано в документации по AuthSub.

После того как вы установили токен сеанса, вы можете использовать стандартные вызовы клиентской библиотеки API данных Google для взаимодействия со службой, не задумываясь о токене. Дополнительные сведения см. в документации по клиентской библиотеке и в руководстве разработчика API данных Google для службы и языка, с которым вы взаимодействуете.

Получение информации о токене сеанса

Если вы хотите проверить, согласны ли ваш клиент и сервер с параметрами маркера, вы можете передать маркер обработчику AuthSubTokenInfo , который возвращает набор пар "имя-значение", содержащих информацию о маркере.

Джава

Map<String, String> tokenInfo = AuthSubUtil.getTokenInfo(sessionToken, null);

Если вы используете безопасный AuthSub, передайте свой закрытый ключ RSA:

Map<String, String> tokenInfo = AuthSubUtil.getTokenInfo(sessionToken, privateKey);

.СЕТЬ

Dictionary<String, String> tokenInfo = AuthSubUtil.GetTokenInfo(sessionToken, null);

Если вы используете безопасный AuthSub, передайте свой закрытый ключ RSA:

Dictionary<String, String> tokenInfo = AuthSubUtil.GetTokenInfo(sessionToken, privateKey);

PHP

$tokenInfo = Zend_Gdata_AuthSub::getAuthSubTokenInfo($sessionToken);

Если вы используете безопасный AuthSub, передайте свой Zend_Gdata_HttpClient , чтобы запрос был подписан вашим закрытым ключом RSA:

$tokenInfo = Zend_Gdata_AuthSub::getAuthSubTokenInfo($sessionToken, $client);

питон

token_info = calendar_service.AuthSubTokenInfo()

Отозвать токен сеанса

Токены сеанса AuthSub не имеют срока действия; ваш клиент может хранить токен сеанса столько времени, сколько необходимо.

Поэтому, когда ваш клиент закончит использовать токен сеанса, он может отозвать токен с помощью обработчика AuthSubRevokeToken , как описано в документации AuthSub.

Например, если вы хотите управлять маркерами традиционным способом, подобным сеансу, ваш клиент может получить маркер в начале сеанса пользователя и отозвать его в конце сеанса пользователя.

Чтобы отозвать токен, используйте в каждой клиентской библиотеке следующее:

Джава

AuthSubUtil.revokeToken(sessionToken, null);

Если вы используете безопасный AuthSub, передайте свой закрытый ключ RSA:

AuthSubUtil.revokeToken(sessionToken, privateKey);

.СЕТЬ

AuthSubUtil.revokeToken(sessionToken, null);

Если вы используете безопасный AuthSub, передайте свой закрытый ключ RSA:

AuthSubUtil.revokeToken(sessionToken, privateKey);

PHP

$wasRevoked = Zend_Gdata_AuthSub::AuthSubRevokeToken($sessionToken);

Если вы используете безопасный AuthSub, передайте свой Zend_Gdata_HttpClient , чтобы запрос был подписан вашим закрытым ключом RSA:

$wasRevoked = Zend_Gdata_AuthSub::AuthSubRevokeToken($sessionToken, $client);

питон

calendar_service.RevokeAuthSubToken()

Дополнительные ресурсы и образцы

Вернуться к вершине

Создание самоподписывающего закрытого ключа и открытого сертификата для использования с безопасным AuthSub

Закрытый ключ используется для создания подписи, которую необходимо включать в каждый запрос. Открытый ключ, встроенный в сертификат, используется Google для проверки подписи. Открытый ключ должен быть 1024-битным ключом RSA, закодированным в сертификате X.509 в формате PEM. Сертификат должен быть отправлен в Google во время регистрации.

В следующих разделах приведены примеры того, как генерировать ключи и сертификаты с помощью двух конкретных инструментов: утилиты OpenSSL и утилиты keytool Java.

Эти примеры не относятся к API данных Google; вы можете использовать одни и те же утилиты для генерации ключей для любых целей.

В примерах предполагается, что ваша компания называется My_Company и находится в Маунтин-Вью, штат Калифорния, США, с доменным именем example.com.

Генерация ключей с помощью OpenSSL

Чтобы создать пару ключей RSA и соответствующий сертификат, вы можете использовать следующую команду:

# 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

Предупреждение . Включение параметра -nodes создает закрытый ключ без пароля для его защиты. Однако вам следует рассмотреть возможность исключения этого параметра для дополнительной безопасности.

Параметр -sha1 указывает, что ключ будет использоваться для создания подписи SHA1.

Параметр -subj указывает идентификатор приложения, которое представляет сертификат.

Параметр -keyout указывает файл, который будет содержать ключи. Этот файл содержит конфиденциальную информацию и должен быть защищен и никому не должен передаваться.

Параметр -out указывает файл, который будет содержать сертификат в формате PEM (который можно отправить в Google при регистрации).

Генерация ключей для клиента .NET

Платформа .NET не понимает ключи или сертификаты, хранящиеся в формате PEM. Поэтому после создания файла .pem требуется дополнительный шаг:

openssl pkcs12 -export -in test_cert.pem -inkey myrsacert.pem -out myrsacert.pfx -name "Testing Certificate"

На этом шаге создается файл PFX из вашего закрытого ключа и сертификата. Этот файл можно импортировать в клиентскую библиотеку .NET для цифровой подписи запросов к API данных Google.

Генерация ключей для Java-клиента

Клиент Java принимает закрытые ключи в формате PKCS#8. После создания ключа/сертификата в соответствии с приведенными выше инструкциями создайте файл .pk8 из сгенерированного файла .pem:

openssl pkcs8 -in myrsakey.pem -topk8 -nocrypt -out myrsakey.pk8

Кроме того, вы можете использовать хранилище ключей Java и утилиту keytool для создания пары ключей RSA и соответствующего сертификата. Используйте следующую команду:

# 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

Предупреждение : « changeme » ​​не является хорошим паролем; это просто пример.

Параметр -dname указывает идентификатор приложения, которое представляет сертификат. Параметр -storepass указывает пароль для защиты хранилища ключей. Параметр -keypass указывает пароль для защиты закрытого ключа.

Чтобы записать сертификат в файл, который можно использовать в инструменте ManageDomains , используйте следующую команду:

# Output the public certificate to a file
keytool -export -rfc -keystore ./Example.jks -storepass changeme \
  -alias Example -file mycert.pem

Вернуться к вершине