Ce document explique quand utiliser OAuth 2.0, quand l'utiliser, comment acquérir des ID client et comment l'utiliser avec la bibliothèque cliente des API Google pour .NET.
Protocole OAuth 2.0
OAuth 2.0 est le protocole d'autorisation utilisé par les API Google. Vous devriez vous familiariser avec le protocole en lisant les liens suivants:
Récupérer des ID client et des secrets
Vous pouvez obtenir ces ID et codes secrets dans la console Google APIs. Il existe différents types d'ID client. Assurez-vous donc d'obtenir le type approprié pour votre application:
- ID client d'application Web
- ID client des applications installées
- ID client de compte de service
Dans chacun des extraits de code ci-dessous (à l'exception du compte de service), vous devez télécharger le code secret du client et le stocker en tant que client_secrets.json
dans votre projet.
Identifiants
Identifiants utilisateur
UserCredential
est une classe d'assistance thread-safe permettant d'utiliser un jeton d'accès pour accéder à des ressources protégées.
Un jeton d'accès expire généralement au bout d'une heure. Une erreur s'affiche ensuite si vous essayez de l'utiliser.
UserCredential
et AuthorizationCodeFlow
se chargent de "l'actualisation" automatique du jeton, ce qui signifie simplement de l'obtention d'un nouveau jeton d'accès.
Pour ce faire, vous devez utiliser un jeton d'actualisation de longue durée, que vous recevez avec le jeton d'accès si vous utilisez le paramètre access_type=offline
pendant le flux de code d'autorisation.
Dans la plupart des applications, il est conseillé de stocker le jeton d'accès des identifiants et le jeton d'actualisation dans un espace de stockage persistant. Sinon, vous devrez présenter à l'utilisateur final une page d'autorisation dans le navigateur toutes les heures, car le jeton d'accès expire une heure après sa réception.
Pour vous assurer que les jetons d'accès et d'actualisation sont conservés, vous pouvez fournir votre propre implémentation de IDataStore
ou utiliser l'une des implémentations suivantes fournies par la bibliothèque:
-
FileDataStore
pour .NET garantit que les identifiants seront persistants dans un fichier.
ServiceAccountCredential
ServiceAccountCredential
est semblable à UserCredential
, mais il remplit un objectif différent.
Google OAuth 2.0 est compatible avec les interactions de serveur à serveur, comme celles entre une application Web et Google Cloud Storage.
L'application à l'origine de la demande doit prouver sa propre identité pour pouvoir accéder à une API, et aucun utilisateur final n'est impliqué.
ServiceAccountCredential
stocke une clé privée, qui permet de signer une requête d'obtention d'un nouveau jeton d'accès.
UserCredential
et ServiceAccountCredential
implémentent IConfigurableHttpClientInitializer
pour que vous puissiez enregistrer chacun d'eux en tant que:
- Gestionnaire de réponses ayant échoué, qui actualisera le jeton s'il reçoit un code d'état HTTP
401
. - Un intercepteur pour intercepter l'en-tête
Authorization
à chaque requête.
Applications installées
Exemple de code utilisant l'API Livres:
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(); ... } } }
-
Dans cet exemple de code, une instance
UserCredential
est créée en appelant la méthodeGoogleWebAuthorizationBroker.AuthorizeAsync
. Cette méthode statique permet d'obtenir les éléments suivants:- Code secret du client (ou flux vers le code secret du client).
- Champs d'application requis.
- Identifiant utilisateur.
- Jeton d'annulation permettant d'annuler une opération.
- Datastore facultatif. Si le data store n'est pas spécifié, la valeur par défaut est un
FileDataStore
avec un dossierGoogle.Apis.Auth
par défaut. Le dossier est créé dansEnvironment.SpecialFolder.ApplicationData
.
-
Le
UserCredential
renvoyé par cette méthode est défini en tant queHttpClientInitializer
surBooksService
(à l'aide de l'initialiseur). Comme expliqué ci-dessus,UserCredential
implémente un initialiseur de client HTTP. -
Notez que dans l'exemple de code ci-dessus, les informations sur le code secret du client sont chargées à partir d'un fichier, mais vous pouvez également effectuer les opérations suivantes:
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"));
Consultez notre exemple de livres.
Applications Web (ASP.NET Core 3)
Les API Google sont compatibles avec OAuth 2.0 pour les applications de serveur Web.
Google.Apis.Auth.AspNetCore3 est la bibliothèque recommandée pour la plupart des scénarios OAuth 2.0 basés sur Google dans les applications ASP.NET Core 3. Elle implémente un gestionnaire d'authentification OpenIdConnect
spécifique à Google. Il accepte l'authentification incrémentielle et définit un IGoogleAuthProvider
injectable pour fournir des identifiants Google pouvant être utilisés avec les API Google.
Cette section explique comment configurer et utiliser Google.Apis.Auth.AspNetCore3. Le code présenté ici est basé sur Google.Apis.Auth.AspNetCore3.IntegrationTests, qui est une application ASP.NET Core 3 standard et entièrement fonctionnelle.
Si vous souhaitez suivre cette documentation sous forme de tutoriel, vous aurez besoin de votre propre application ASP.NET Core 3 et suivre ces étapes comme condition préalable.
Conditions préalables
- Installez le package Google.Apis.Auth.AspNetCore3.
- Comme nous utilisons l'API Google Drive, vous devez également installer le package Google.Apis.Drive.v3.
- Créez un projet Google Cloud si vous n'en avez pas encore. Pour ce faire, suivez ces instructions. Il s'agit du projet pour lequel votre application est identifiée.
- Assurez-vous d'activer l'API Google Drive. Pour activer les API, suivez ces instructions.
-
Créez des identifiants d'autorisation qui permettront à Google d'identifier votre application. Suivez
ces instructions pour créer des identifiants d'autorisation et télécharger le fichier
client_secrets.json
. Deux points forts :- Notez que les identifiants doivent être de type Web application (Application Web).
- Pour exécuter cette application, le seul URI de redirection à ajouter est
https://localhost:5001/signin-oidc
.
Configurer votre application pour qu'elle utilise Google.Apis.Auth.AspNetCore3
Google.Apis.Auth.AspNetCore3 est configuré dans la classe Startup
ou une alternative similaire que vous pourriez utiliser. Les extraits suivants sont extraits de
Startup.cs
dans le projet Google.Apis.Auth.AspNetCore3.IntegrationTests.
-
Ajoutez la directive d'utilisation suivante à votre fichier
Startup.cs
.using Google.Apis.Auth.AspNetCore3;
-
Dans la méthode
Startup.ConfigureServices
, ajoutez le code suivant, puis remplacez les espaces réservés "ID client" et "Code secret du client" par les valeurs contenues dans le fichierclient_secrets.json
. Vous pouvez charger ces valeurs directement à partir du fichier JSON ou les stocker de toute autre manière sécurisée. Examinez la méthodeClientInfo.Load
dans le projet Google.Apis.Auth.AspNetCore3.IntegrationTests pour savoir comment charger ces valeurs directement à partir du fichier 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}; }); }
-
Dans la méthode
Startup.Configure
, veillez à ajouter au pipeline les composants d'authentification et d'autorisation ASP.NET Core 3, ainsi que les redirections HTTPS :public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... app.UseHttpsRedirection(); ... app.UseAuthentication(); app.UseAuthorization(); ... }
Utiliser les identifiants de l'utilisateur pour accéder aux API Google en son nom
Vous êtes maintenant prêt à ajouter à vos contrôleurs des méthodes d'action qui nécessitent que les identifiants de l'utilisateur accèdent aux API Google en son nom. L'extrait de code suivant montre comment répertorier les fichiers sur le compte Google Drive de l'utilisateur authentifié. Notez deux choses principales:
-
L'utilisateur doit non seulement être authentifié, mais il doit également avoir accordé le champ d'application
https://www.googleapis.com/auth/drive.readonly
à votre application, que vous spécifiez via l'attributGoogleScopedAuthorize
. -
Nous utilisons le mécanisme d'injection de dépendances standard d'ASP.NET Core 3 pour recevoir un
IGoogleAuthProvider
qui nous permet d'obtenir les identifiants de l'utilisateur.
Le code:
-
Commencez par ajouter les instructions d'utilisation suivantes à votre contrôleur.
using Google.Apis.Auth.AspNetCore3; using Google.Apis.Auth.OAuth2; using Google.Apis.Drive.v3; using Google.Apis.Services;
-
Ajoutez l'action du contrôleur comme suit (et ajoutez-y une vue simple qui reçoit un modèle
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); }
Et ce sont les bases. Vous pouvez consulter la méthode
HomeController.cs
du projet Google.Apis.Auth.AspNetCore3.IntegrationTests pour découvrir comment obtenir les résultats suivants:
- Authentification des utilisateurs uniquement, sans champ d'application spécifique
- Fonctionnalité de déconnexion
- Autorisation incrémentielle via du code. Notez que l'extrait de code ci-dessus indique une autorisation incrémentielle via des attributs.
- Examiner les niveaux d'accès actuellement accordés
- Examiner les jetons d'accès et d'actualisation
- Forcez l'actualisation du jeton d'accès. Notez que vous n'avez pas à effectuer cette opération vous-même, car Google.Apis.Auth.AspNetCore3 détectera si le jeton d'accès a expiré ou est sur le point d'expirer, et l'actualisera automatiquement.
Compte de service
Les comptes de service sont également compatibles avec les API Google. Contrairement au scénario dans lequel une application cliente demande l'accès aux données d'un utilisateur final, les comptes de service fournissent un accès aux données de l'application cliente.
Votre application cliente signe la requête de jeton d'accès à l'aide d'une clé privée téléchargée à partir de la console Google APIs. Après avoir créé un ID client, vous devez choisir le type d'application "Compte de service", puis télécharger la clé privée. Consultez notre exemple de compte de service utilisant l'API 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(); } } }
L'exemple de code ci-dessus crée un objet ServiceAccountCredential
.
Les champs d'application requis sont définis, et un appel à FromCertificate
est effectué, qui charge la clé privée à partir du X509Certificate2
donné.
Comme dans tous les autres exemples de code, l'identifiant est défini sur HttpClientInitializer
.