AuthSub en las bibliotecas cliente del protocolo de datos de Google

Advertencia: Esta página trata sobre las API anteriores de Google, las API de datos de Google, y solo es relevante para las API que aparecen en el directorio de las API de datos de Google, muchas de las cuales se reemplazaron con API más nuevas. Para obtener información sobre una API nueva específica, consulta la documentación de la API nueva. Para obtener información sobre cómo autorizar solicitudes con una API más reciente, consulta Autenticación y autorización de cuentas de Google.

En este documento, se describe cómo usar las bibliotecas cliente de la API de datos de Google a fin de conectarse a la Autenticación de AuthSub para aplicaciones web de Google.

La interfaz de AuthSub permite que una aplicación basada en la Web acceda a un servicio de Google en nombre de un usuario. Para mantener un alto nivel de seguridad, la interfaz AuthSub permite que la aplicación obtenga un token de autenticación sin necesidad de manejar la información de acceso de la cuenta del usuario.

Las bibliotecas cliente de la API de datos de Google proporcionan métodos para ayudarte a usar AuthSub en tu aplicación web. Específicamente, existen métodos para construir la URL de la solicitud, obtener un token de autenticación de un solo uso, intercambiar el token de un solo uso por un token de sesión y firmar la solicitud.

Nota: La biblioteca cliente de JavaScript tiene su propio tipo de AuthSub, llamado AuthSubJS. Para obtener información sobre cómo utilizar AuthSubJS en tus aplicaciones de JavaScript, consulta Cómo utilizar la autenticación "AuthSub" con la biblioteca cliente de JavaScript.

Público

Este documento está destinado a programadores que desean que sus aplicaciones basadas en la Web accedan a los servicios de Google en nombre de los usuarios mediante las bibliotecas cliente de las API de datos de Google.

En este documento, se supone que estás familiarizado con la interfaz de AuthSub y con el proceso general para incorporar AuthSub a tu aplicación web. Si quieres obtener una descripción completa del protocolo de AuthSub, consulta Autenticación de AuthSub para aplicaciones web.

Usa AuthSub y las API de datos de Google sin las bibliotecas cliente

Si deseas que tu cliente de aplicación web interactúe con un servicio de datos de Google usando AuthSub como sistema de autenticación, todo lo que necesitas saber es en Autenticación de AuthSub para aplicaciones web. Si no lo desea, no es necesario que use las bibliotecas cliente de las API de datos de Google.

A continuación, se describe el modo en que tu aplicación puede autenticar a un usuario con AuthSub:

Tu aplicación construye la URL de AuthSub adecuada y luego envía al usuario a esa URL para que pueda acceder; el sistema de AuthSub envía al usuario de vuelta a la URL en el sitio que especificaste y muestra un token de uso único; tu aplicación cambia de manera opcional ese token por un token de sesión; luego tu aplicación envía el token en el encabezado de autorización con cada solicitud que la aplicación envía al servicio.

Las bibliotecas cliente de las API de datos de Google simplifican este proceso de autorización, ya que manejan varios detalles por ti. En este documento, se explica cómo hacerlo.

Cómo trabajar con AuthSub y las API de datos de Google: ejemplos de biblioteca cliente

En esta sección, se muestra un ejemplo del uso de los métodos de la biblioteca cliente de las API de datos de Google para seguir los pasos descritos en la sección "Trabaja con AuthSub" de la documentación de AuthSub.

En este ejemplo, integramos la interfaz de AuthSub a una aplicación web que interactúa con Calendario de Google (aunque no necesitas saber nada sobre Calendario de Google para seguir el ejemplo). En el ejemplo, se supone que la aplicación web está alojada en example.com.

Decide qué tipo de token usar (session=0 o session=1).

Puedes elegir usar tokens de uso único (session=0) o tokens de sesión (session=1). En este documento, se usarán tokens de sesión, ya que son más útiles en las aplicaciones que realizan varias solicitudes a la API. Como se explica en la documentación de AuthSub, si decides usar tokens de sesión en tu aplicación web, deberás administrar el almacenamiento de tokens tú mismo. Este documento no cubre la administración de tokens. Además, ten en cuenta que los tokens solicitados con session=0 no se pueden intercambiar (actualizar) más tarde por un token de sesión de larga duración.

Decida si desea registrar su aplicación web (secure=0 o secure=1)

AuthSub se puede usar en tres modos diferentes: sin registrar, registrado y registrado con seguridad encantada. En el resto de este documento, se hará referencia a la última opción como AuthSub seguro. Aunque el modo no registrado o registrado es más sencillo de configurar que AuthSub seguro, Google te recomienda usar tokens seguros para su seguridad encantada.

Cómo registrarse

Si eliges Registro para aplicaciones basadas en la Web, tendrás los siguientes beneficios:

  1. Un nivel de seguridad más alto.
  2. Ser de confianza de Google (no se muestra ninguna advertencia al usuario en la página de autorización de Google)

AuthSub registrada y segura

Si decides usar AuthSub seguro, deberás crear una clave privada RSA y un par de certificados públicos autofirmados, además de registrar tu aplicación web. Consulta Generar claves y certificados para usarlos con el modo registrado (a continuación) a fin de obtener ejemplos de la creación de certificados X.509.

Determine el alcance de su acceso a los datos

Cada servicio de Google define un valor de scope que determina (y posiblemente reduce) el acceso de un token a los datos del usuario. Consulta las Preguntas frecuentes para ver la lista de valores scope disponibles.

Como decidimos interactuar con la API del Calendario de Google, el scope debería ser http://www.google.com/calendar/feeds/.

Nota: Siempre debes establecer el valor de alcance en la URL más amplia posible, a menos que necesites una restricción más precisa. Por ejemplo, un alcance más limitado, como scope=http://www.google.com/calendar/feeds/default/allcalendars/full, restringirá el acceso del token solo a todos los calendarios o el feed completo. Si usas scope=http://www.google.com/calendar/feeds/, se permitirá el acceso a todos los feeds de Calendario: http://www.google.com/calendar/feeds/*.

Tokens de alcance múltiple

Para crear tokens que accedan a varias API de datos de Google, separe cada alcance con un espacio codificado en URL. En el siguiente ejemplo, se crea un token que tendrá acceso a los datos de Contactos de Google y Calendario de Google de un usuario.

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

Solicita un token de autenticación de un solo uso

A fin de adquirir un token de AuthSub para un usuario y servicio determinados, tu aplicación debe redireccionar al usuario a la URL AuthSubRequest, que le solicita que acceda a su Cuenta de Google. (Para obtener más información sobre la URL AuthSubRequest, consulta la Autenticación de AuthSub para aplicaciones web completa).

A fin de construir la URL AuthSubRequest en tu aplicación, usa lo siguiente para cada biblioteca cliente:

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

Si deseas autenticar a los usuarios de tu dominio de G Suite, haz lo siguiente:

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

Si deseas autenticar a los usuarios de tu dominio de G Suite, haz lo siguiente:

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

Si deseas autenticar a los usuarios de tu dominio de G Suite, haz lo siguiente:

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)

Si deseas autenticar a los usuarios de tu dominio de G Suite, haz lo siguiente:

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)

Después de construir la URL "next", la aplicación puede usarla de varias maneras para enviar al usuario al controlador AuthSubRequest. El enfoque más común es mostrar una página que le indique al usuario que debe seguir un vínculo para autorizar a tu aplicación a acceder a su cuenta de Google y que luego adjunte la URL de la solicitud al vínculo. Por ejemplo, podrías generar la siguiente string en tu aplicación web:

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

El usuario sigue el vínculo a la página de AuthSub en Google y accede. El sistema AuthSub luego redirecciona al usuario de vuelta a tu aplicación usando la URL "siguiente" que proporcionaste.

Extrae el token de un solo uso

Cuando Google redirecciona a su aplicación, el token se agrega a la URL "next" como parámetro de consulta. En el caso de los ejemplos anteriores, después de que el usuario accede, Google redirecciona a una URL como http://www.example.com/RetrieveToken?token=DQAADKEDE. Tu aplicación debe extraer el valor del token de su parámetro de consulta de URL.

Si tu aplicación configura una cookie de autenticación en el navegador del usuario antes de enviarlo al sistema de AuthSub, cuando Google redireccione a la URL "siguiente", la aplicación podrá leer la cookie de autenticación para reconocer qué usuario llegó a esa URL. Puedes usar esa cookie para asociar un ID de usuario en tu aplicación con el token de AuthSub recuperado de Google.

Las bibliotecas cliente proporcionan métodos convenientes para extraer el token de un solo uso:

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

Si usas AuthSub seguro, asegúrate de establecer tu clave privada RSA para que se cree un 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)

Solicita un token de sesión

El token que recuperas de la URL siempre es un token de un solo uso. El siguiente paso es actualizar ese token para un token de sesión de larga duración mediante la URL AuthSubSessionToken, como se describe en la documentación completa de Autenticación de AuthSub para aplicaciones web. Si usas AuthSub seguro, deberás configurar tu clave privada RSA antes de hacer el intercambio. A continuación, se incluyen algunos ejemplos que usan cada una de las bibliotecas cliente:

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

Para usar AuthSub seguro, pasa tu clave privada RSA a exchangeForSessionToken en lugar de pegar 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

Para usar AuthSub seguro, pasa tu clave privada RSA a exchangeForSessionToken en lugar de pegar 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

Para AuthSub seguro, el intercambio requiere que primero configures una Zend_Gdata_HttpClient y establezcas tu clave privada RSA con 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

Nota: El proceso es el mismo para la autenticación segura de AuthSub, siempre que hayas usado gdata.auth.extract_auth_sub_token_from_url(url, rsa_key=rsa_key) a fin de extraer el token de uso único.

Nota: Cuando usas AuthSub seguro, tu clave privada no se envía a través de la red. Las bibliotecas cliente envían la firma única generada mediante la firma de la solicitud con tu clave, no la clave en sí.

Usa el token de sesión

Puedes usar el token de sesión para autenticar las solicitudes al servidor; para ello, coloca el token en el encabezado de autorización, como se describe en la documentación de AuthSub.

Después de configurar el token de sesión, puedes usar las llamadas a la biblioteca cliente estándar de las API de datos de Google para interactuar con el servicio, sin tener que pensar en el token. Para obtener más información, consulta la documentación de la biblioteca cliente y la guía para desarrolladores de las API de datos de Google para el servicio y el lenguaje con los que interactúas.

Recupera información sobre un token de sesión

Si quieres probar que el cliente y el servidor acepten los parámetros del token, puedes pasar el token al controlador AuthSubTokenInfo, que muestra un conjunto de pares nombre-valor que contienen información sobre el token.

Java

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

Si usas AuthSub seguro, pasa tu clave privada RSA:

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

.NET

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

Si usas AuthSub seguro, pasa tu clave privada RSA:

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

PHP

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

Si usas AuthSub seguro, pasa tu Zend_Gdata_HttpClient para que la solicitud se firme con tu clave privada RSA:

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

Python

token_info = calendar_service.AuthSubTokenInfo()

Revocar un token de sesión

Los tokens de sesión de AuthSub no vencen; tu cliente puede almacenar el token de sesión durante el tiempo que sea necesario.

Por lo tanto, cuando el cliente termine de usar el token de sesión, podrá revocarlo con el controlador AuthSubRevokeToken, como se describe en la documentación de AuthSub.

Por ejemplo, si desea administrar tokens de manera similar a una sesión tradicional, su cliente puede obtener un token al comienzo de la sesión de un usuario y revocarlo al final de la sesión.

Para revocar un token, usa lo siguiente en cada biblioteca cliente:

Java

AuthSubUtil.revokeToken(sessionToken, null);

Si usas AuthSub seguro, pasa tu clave privada RSA:

AuthSubUtil.revokeToken(sessionToken, privateKey);

.NET

AuthSubUtil.revokeToken(sessionToken, null);

Si usas AuthSub seguro, pasa tu clave privada RSA:

AuthSubUtil.revokeToken(sessionToken, privateKey);

PHP

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

Si usas AuthSub seguro, pasa tu Zend_Gdata_HttpClient para que la solicitud se firme con tu clave privada RSA:

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

Python

calendar_service.RevokeAuthSubToken()

Recursos y muestras adicionales

Volver al principio

Genera una clave privada autofirmada y un certificado público para usar con AuthSub seguro

La clave privada se usa para generar una firma, que debe incluirse en cada solicitud. Google utiliza la clave pública incorporada en el certificado para verificar la firma. La clave pública debe ser una clave RSA de 1,024 bits codificada en un certificado X.509 en formato PEM. El certificado debe enviarse a Google en el momento del registro.

En las siguientes secciones, se proporcionan ejemplos de cómo generar claves y certificados con dos herramientas en particular: la utilidad OpenSSL y la utilidad keytool de Java.

Estos ejemplos no son específicos para las API de datos de Google; puedes usar las mismas utilidades para generar claves con cualquier propósito.

En los ejemplos, se supone que su empresa se llama My_Company y se encuentra en Mountain View, California, EE.UU., con el nombre de dominio example.com.

Genera claves con OpenSSL

Para crear un par de claves RSA y el certificado correspondiente, puedes usar el siguiente comando:

# 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

Advertencia: Incluir el parámetro -nodes crea una clave privada sin una contraseña para protegerla. Sin embargo, deberías considerar omitir este parámetro para mayor seguridad.

El parámetro -sha1 especifica que la clave se usará para generar firmas SHA1.

El parámetro -subj especifica la identidad de la aplicación que representa el certificado.

El parámetro -keyout especifica el archivo que contendrá las claves. Este archivo contiene información sensible y debe protegerse y no compartirse con nadie.

El parámetro -out especifica el archivo que contendrá el certificado en formato PEM (que se puede enviar a Google durante el registro).

Genera claves para el cliente .NET

El marco de trabajo .NET no comprende las claves ni los certificados almacenados en formato PEM. Por lo tanto, se debe realizar un paso adicional después de crear el archivo .pem:

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

Este paso genera un archivo PFX desde tu clave privada y certificado. Este archivo se puede importar a la biblioteca cliente de .NET para firmar de forma digital las solicitudes realizadas a las API de datos de Google.

Genera claves para el cliente de Java

El cliente Java acepta claves privadas en formato PKCS#8. Después de generar una clave o un certificado con las instrucciones anteriores, crea un archivo .pk8 a partir de tu archivo .pem generado:

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

Como alternativa, puedes usar el almacén de claves de Java y la utilidad de keytool para crear un par de claves RSA y el certificado correspondiente. Usa el siguiente comando:

# 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

Advertencia: "changeme" no es una contraseña segura, es solo un ejemplo.

El parámetro -dname especifica la identidad de la aplicación que representa el certificado. El parámetro -storepass especifica la contraseña para proteger el almacén de claves. El parámetro -keypass especifica la contraseña para proteger la clave privada.

Para escribir el certificado en un archivo que pueda usarse en la herramienta ManageDomains, use el siguiente comando:

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

Volver al principio