En este documento, se describe OAuth 2.0, cuándo utilizarlo, cómo adquirir IDs de cliente, y cómo utilizarla con la biblioteca cliente de las APIs de Google para .NET.
Protocolo OAuth 2.0
OAuth 2.0 es el protocolo de autorización que usan las APIs de Google. Lee los siguientes vínculos para familiarizarte con el protocolo:
Adquiere ID de cliente y secretos
Puedes obtener IDs de cliente y secretos en la Consola de APIs de Google. Existen diferentes tipos de IDs de cliente, así que asegúrate de obtener el tipo correcto para tu aplicación:
- IDs de cliente de aplicación web
- IDs de cliente de las aplicaciones instaladas
- IDs de cliente de las cuentas de servicio
En cada uno de los fragmentos de código que aparecen a continuación (excepto en la cuenta de servicio uno), debes descargar el archivo
y almacénalo como client_secrets.json
en tu proyecto.
Credenciales
Credenciales de usuario
UserCredential
es una clase auxiliar segura para subprocesos que sirve para usar un token de acceso a fin de acceder a recursos protegidos.
Los tokens de acceso suelen vencer después de 1 hora
después de lo cual recibirás un error si intentas usarlo.
UserCredential
y
AuthorizationCodeFlow
se encargará de “actualizar” automáticamente el token, lo que simplemente significa obtener
un token de acceso nuevo.
Esto se hace usando un token de actualización de larga duración, que recibes junto con el
el token de acceso, si usas
access_type=offline
durante el flujo de código de autorización.
En la mayoría de las aplicaciones, es recomendable almacenar los el token de acceso de la credencial y el token de actualización en el almacenamiento persistente. De lo contrario, deberás presentar al usuario final un de autorización en el navegador cada hora, ya que el nombre el token caduca una hora después de haberlo recibido.
Para asegurarte de que persistan los tokens de acceso y actualización,
puedes implementar tu propia implementación
IDataStore
:
o puedes usar una de las siguientes implementaciones que proporciona la biblioteca:
-
FileDataStore
para .NET garantiza que la credencial sea persistente en un archivo.
ServiceAccountCredential
ServiceAccountCredential
es similar a UserCredential
, pero tiene un propósito diferente.
Google OAuth 2.0 admite interacciones servidor a servidor, como las que existen entre una aplicación web y Google Cloud Storage.
La aplicación solicitante debe demostrar su propia identidad para obtener acceso a una API, y no es necesario que el usuario final participe.
ServiceAccountCredential
almacena una clave privada que se usa para firmar una solicitud y obtener un token de acceso nuevo.
UserCredential
y ServiceAccountCredential
se implementan
IConfigurableHttpClientInitializer
por lo que puedes registrar cada uno de ellos como:
- Un controlador de respuestas sin éxito,
por lo que actualizará el token si recibe un código de estado HTTP
401
. - Un interceptor para interceptar el
Authorization
el encabezado en cada solicitud.
Aplicaciones instaladas
Código de muestra con la API de Libros:
using System; using System.IO; using System.Threading; using System.Threading.Tasks; using Google.Apis.Auth.OAuth2; using Google.Apis.Books.v1; using Google.Apis.Books.v1.Data; using Google.Apis.Services; using Google.Apis.Util.Store; namespace Books.ListMyLibrary { /// <summary> /// Sample which demonstrates how to use the Books API. /// https://developers.google.com/books/docs/v1/getting_started /// <summary> internal class Program { [STAThread] static void Main(string[] args) { Console.WriteLine("Books API Sample: List MyLibrary"); Console.WriteLine("================================"); try { new Program().Run().Wait(); } catch (AggregateException ex) { foreach (var e in ex.InnerExceptions) { Console.WriteLine("ERROR: " + e.Message); } } Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } private async Task Run() { UserCredential credential; using (var stream = new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read)) { credential = await GoogleWebAuthorizationBroker.AuthorizeAsync( GoogleClientSecrets.Load(stream).Secrets, new[] { BooksService.Scope.Books }, "user", CancellationToken.None, new FileDataStore("Books.ListMyLibrary")); } // Create the service. var service = new BooksService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = "Books API Sample", }); var bookshelves = await service.Mylibrary.Bookshelves.List().ExecuteAsync(); ... } } }
-
En este código de muestra, se crea una nueva instancia de
UserCredential
llamando alGoogleWebAuthorizationBroker.AuthorizeAsync
. Este método estático obtiene lo siguiente:- El secreto del cliente (o una transmisión al secreto del cliente).
- Los permisos necesarios
- Es el identificador del usuario.
- El token de cancelación para cancelar una operación.
- Un almacén de datos opcional. Si no se especifica el almacén de datos, el valor predeterminado es
FileDataStore
. con una carpetaGoogle.Apis.Auth
predeterminada. La carpeta se crea enEnvironment.SpecialFolder.ApplicationData
.
-
La
UserCredential
que muestra este método se establece comoHttpClientInitializer
. enBooksService
(con el inicializador). Como se explicó anteriormente,UserCredential
implementa un Inicializador de cliente HTTP. -
Ten en cuenta que, en el código de muestra anterior, la información del secreto del cliente se carga desde un archivo, pero también puedes hacer lo siguiente:
credential = await GoogleWebAuthorizationBroker.AuthorizeAsync( new ClientSecrets { ClientId = "PUT_CLIENT_ID_HERE", ClientSecret = "PUT_CLIENT_SECRETS_HERE" }, new[] { BooksService.Scope.Books }, "user", CancellationToken.None, new FileDataStore("Books.ListMyLibrary"));
Consulta nuestra Muestra de libros.
Aplicaciones web (ASP.NET Core 3)
Compatibilidad con las APIs de Google OAuth 2.0 para aplicaciones de servidor web
El
Google.Apis.Auth.AspNetCore3 es la biblioteca que se recomienda usar para la mayoría de las aplicaciones basadas en
Situaciones de OAuth 2.0 en aplicaciones de ASP.NET Core 3. Implementa una interfaz de programación
Controlador de autenticación OpenIdConnect
. Admite autenticación incremental y define un modelo
IGoogleAuthProvider
para proporcionar credenciales de Google que se pueden usar con las APIs de Google.
En esta sección, se describe cómo configurar y usar Google.Apis.Auth.AspNetCore3. El código que se muestra se basa en Google.Apis.Auth.AspNetCore3.IntegrationTests, una ASP.NET estándar y completamente funcional Core 3.
Si deseas seguir esta documentación como un instructivo, necesitarás tu propia ASP.NET y completar estos pasos como prerrequisito.
Requisitos previos
- Instala el Google.Apis.Auth.AspNetCore3.
- Estamos usando la API de Google Drive, por lo que también debes instalar Google.Apis.Drive.v3 .
- Crea un proyecto de Google Cloud si aún no tienes uno. Seguir estas instrucciones para hacerlo. Este será el proyecto con el que se identificará tu app.
- Asegúrate de habilitar la API de Google Drive. Para habilitar las APIs, sigue estos pasos: estas instrucciones.
-
Crea credenciales de autorización que le permitan a Google identificar tu app. Seguir
estas instrucciones para crear credenciales de autorización y descargar la
Archivo
client_secrets.json
. Dos aspectos destacados:- Ten en cuenta que las credenciales el tipo debe ser Web application.
- Para ejecutar esta app, el único URI de redireccionamiento que debes agregar es
https://localhost:5001/signin-oidc
Configura tu aplicación para que use Google.Apis.Auth.AspNetCore3
Google.Apis.Auth.AspNetCore3 se configura en la clase Startup
o similar.
alternativa que podrías estar usando. Los siguientes fragmentos se extrajeron de
Startup.cs
en el proyecto Google.Apis.Auth.AspNetCore3.IntegrationTests.
-
Agrega la siguiente directiva de uso a tu archivo
Startup.cs
.using Google.Apis.Auth.AspNetCore3;
-
En el método
Startup.ConfigureServices
, agrega el siguiente código y cambia el Los marcadores de posición ID de cliente y secreto del cliente con los valores incluidos en archivoclient_secrets.json
. Puedes cargar estos valores directamente desde el archivo JSON o puedes almacenarlos de cualquier otra forma segura. Consulta laClientInfo.Load
en Google.Apis.Auth.AspNetCore3.IntegrationTests para ver un ejemplo de cómo cargar estos valores directamente desde el archivo JSON.public void ConfigureServices(IServiceCollection services) { ... // This configures Google.Apis.Auth.AspNetCore3 for use in this app. services .AddAuthentication(o => { // This forces challenge results to be handled by Google OpenID Handler, so there's no // need to add an AccountController that emits challenges for Login. o.DefaultChallengeScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme; // This forces forbid results to be handled by Google OpenID Handler, which checks if // extra scopes are required and does automatic incremental auth. o.DefaultForbidScheme = GoogleOpenIdConnectDefaults.AuthenticationScheme; // Default scheme that will handle everything else. // Once a user is authenticated, the OAuth2 token info is stored in cookies. o.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; }) .AddCookie() .AddGoogleOpenIdConnect(options => { options.ClientId = {YOUR_CLIENT_ID}; options.ClientSecret = {YOUR_CLIENT_SECRET}; }); }
-
En el método
Startup.Configure
, asegúrate de agregar la autenticación de ASP.NET Core 3. y los componentes de middleware de autorización a la canalización, así como los redireccionamientos HTTPS:public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... app.UseHttpsRedirection(); ... app.UseAuthentication(); app.UseAuthorization(); ... }
Usar la credencial de usuario para acceder a las APIs de Google en su nombre
Ahora puedes agregar métodos de acción a tus controladores que requieran la credencial de usuario para realizar esta acción. acceder a las APIs de Google en su nombre. En el siguiente fragmento, se muestra cómo enumerar los archivos en la cuenta de Google Drive del usuario autenticado. Observa dos cosas sobre todo:
-
El usuario no solo necesita estar autenticado, sino que también debe haber otorgado
https://www.googleapis.com/auth/drive.readonly
a tu aplicación, que que especifiques mediante el atributoGoogleScopedAuthorize
. -
Utilizamos el mecanismo de inserción de dependencias estándar de ASP.NET Core 3 para recibir una
IGoogleAuthProvider
, que usamos para obtener las credenciales del usuario.
El código:
-
Primero, agrega lo siguiente con directivas a tu controlador.
using Google.Apis.Auth.AspNetCore3; using Google.Apis.Auth.OAuth2; using Google.Apis.Drive.v3; using Google.Apis.Services;
-
Agrega la acción del controlador como se indica a continuación (y acompáñala con una vista simple
que recibe un modelo
IList<string>
):/// <summary> /// Lists the authenticated user's Google Drive files. /// Specifying the <see cref="GoogleScopedAuthorizeAttribute"> will guarantee that the code /// executes only if the user is authenticated and has granted the scope specified in the attribute /// to this application. /// </summary> /// <param name="auth">The Google authorization provider. /// This can also be injected on the controller constructor.</param> [GoogleScopedAuthorize(DriveService.ScopeConstants.DriveReadonly)] public async Task<IActionResult> DriveFileList([FromServices] IGoogleAuthProvider auth) { GoogleCredential cred = await auth.GetCredentialAsync(); var service = new DriveService(new BaseClientService.Initializer { HttpClientInitializer = cred }); var files = await service.Files.List().ExecuteAsync(); var fileNames = files.Files.Select(x => x.Name).ToList(); return View(fileNames); }
Estos son los conceptos básicos. Puedes consultar
HomeController.cs
del proyecto Google.Apis.Auth.AspNetCore3.IntegrationTests
para descubrir cómo lograr lo siguiente:
- Solo autenticación de usuarios, sin permisos específicos
- Función para salir
- Autorización incremental a través de código Ten en cuenta que el fragmento anterior muestra imágenes autorización mediante atributos.
- Examinar los permisos otorgados actualmente
- Examina los tokens de acceso y actualización
- Fuerza la actualización del token de acceso. Observa que no tienes que hacerlo por tu cuenta Google.Apis.Auth.AspNetCore3 detectará si el token de acceso venció o está a punto de caducar. y la actualizará automáticamente.
Cuenta de servicio
Las APIs de Google también admiten Cuentas de servicio. A diferencia de la situación en la que una aplicación cliente solicita acceso a los datos de un usuario final, de servicio proporcionan acceso a los datos propios de la aplicación cliente.
Tu aplicación cliente firma la solicitud de un token de acceso usando una clave privada descargada desde la Consola de APIs de Google. Después de crear un nuevo ID de cliente, debes elegir una "Cuenta de servicio" el tipo de aplicación y, luego, descargar la clave privada. Consulta nuestra cuenta de servicio con la API de Google Plus.
using System; using System.Security.Cryptography.X509Certificates; using Google.Apis.Auth.OAuth2; using Google.Apis.Plus.v1; using Google.Apis.Plus.v1.Data; using Google.Apis.Services; namespace Google.Apis.Samples.PlusServiceAccount { /// <summary> /// This sample demonstrates the simplest use case for a Service Account service. /// The certificate needs to be downloaded from the Google API Console /// <see cref="https://console.cloud.google.com/"> /// "Create another client ID..." -> "Service Account" -> Download the certificate, /// rename it as "key.p12" and add it to the project. Don't forget to change the Build action /// to "Content" and the Copy to Output Directory to "Copy if newer". /// </summary> public class Program { // A known public activity. private static String ACTIVITY_ID = "z12gtjhq3qn2xxl2o224exwiqruvtda0i"; public static void Main(string[] args) { Console.WriteLine("Plus API - Service Account"); Console.WriteLine("=========================="); String serviceAccountEmail = "SERVICE_ACCOUNT_EMAIL_HERE"; var certificate = new X509Certificate2(@"key.p12", "notasecret", X509KeyStorageFlags.Exportable); ServiceAccountCredential credential = new ServiceAccountCredential( new ServiceAccountCredential.Initializer(serviceAccountEmail) { Scopes = new[] { PlusService.Scope.PlusMe } }.FromCertificate(certificate)); // Create the service. var service = new PlusService(new BaseClientService.Initializer() { HttpClientInitializer = credential, ApplicationName = "Plus API Sample", }); Activity activity = service.Activities.Get(ACTIVITY_ID).Execute(); Console.WriteLine(" Activity: " + activity.Object.Content); Console.WriteLine(" Video: " + activity.Object.Attachments[0].Url); Console.WriteLine("Press any key to continue..."); Console.ReadKey(); } } }
El código de muestra anterior crea un
ServiceAccountCredential
Se configuran los permisos necesarios y hay una llamada a FromCertificate
que carga la clave privada del X509Certificate2
determinado.
Al igual que en todos los demás códigos de muestra, la credencial se establece como HttpClientInitializer
.