In diesem Dokument wird OAuth 2.0 beschrieben, wann es verwendet werden sollte, wie Sie Client-IDs abrufen und wie Sie es mit der Google API-Clientbibliothek für .NET verwenden.
OAuth 2.0-Protokoll
OAuth 2.0 ist das Autorisierungsprotokoll, das von Google APIs verwendet wird. Machen Sie sich mit dem Protokoll vertraut. Lesen Sie dazu die folgenden Links:
Client-IDs und Secrets abrufen
Client-IDs und Secrets finden Sie in der Google API Console. Es gibt verschiedene Arten von Client-IDs. Achten Sie darauf, den richtigen Typ für Ihre Anwendung zu verwenden:
- Client-IDs für Webanwendungen
- Client-IDs von installierten Apps
- Client-IDs von Dienstkonten
In jedem der angezeigten Code-Snippets (außer dem für das Dienstkonto) müssen Sie das Client-Secret herunterladen und in Ihrem Projekt als client_secrets.json
speichern.
Anmeldedaten
Nutzeranmeldedaten
UserCredential
ist eine threadsichere Hilfsklasse, mit der ein Zugriffstoken für den Zugriff auf geschützte Ressourcen verwendet wird.
Ein Zugriffstoken läuft in der Regel nach einer Stunde ab. Danach wird bei Verwendung des Tokens ein Fehler zurückgegeben.
UserCredential
und AuthorizationCodeFlow
sorgen dafür, dass das Token automatisch „aktualisiert“ wird, was bedeutet, dass ein neues Zugriffstoken abgerufen wird.
Dazu wird ein langlebiges Aktualisierungstoken verwendet, das Sie zusammen mit dem Zugriffstoken erhalten, wenn Sie während des Autorisierungscode-Ablaufs den Parameter access_type=offline
verwenden.
Bei den meisten Anwendungen empfiehlt es sich, das Zugriffs- und das Aktualisierungstoken der Anmeldedaten im dauerhaften Speicher zu speichern. Andernfalls müssen Sie dem Endnutzer stündlich eine Autorisierungsseite im Browser anzeigen, da das Zugriffstoken eine Stunde nach Erhalt abläuft.
Damit die Zugriffs- und Aktualisierungstokens erhalten bleiben, können Sie eine eigene Implementierung von IDataStore
bereitstellen oder eine der folgenden Implementierungen der Bibliothek verwenden:
-
FileDataStore
für .NET sorgt dafür, dass die Anmeldedaten in einer Datei dauerhaft gespeichert werden.
ServiceAccountCredential
ServiceAccountCredential
ähnelt UserCredential
, hat aber einen anderen Zweck.
Google OAuth 2.0 unterstützt Server-zu-Server-Interaktionen, z. B. zwischen einer Webanwendung und Google Cloud Storage.
Die anfragende Anwendung muss ihre eigene Identität nachweisen, um Zugriff auf eine API zu erhalten. Ein Endnutzer muss nicht beteiligt sein.
ServiceAccountCredential
speichert einen privaten Schlüssel, mit dem eine Anfrage zum Abrufen eines neuen Zugriffstokens signiert wird.
Sowohl UserCredential
als auch ServiceAccountCredential
implementieren IConfigurableHttpClientInitializer
. Sie können sie daher so registrieren:
- Ein Handler für fehlgeschlagene Antworten, der das Token aktualisiert, wenn der HTTP-Statuscode
401
empfangen wird. - Ein Interceptor, der den
Authorization
-Header bei jeder Anfrage abfängt.
Installierte Apps
Beispielcode mit der Books API:
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(); ... } } }
-
In diesem Beispielcode wird eine neue
UserCredential
-Instanz erstellt, indem die MethodeGoogleWebAuthorizationBroker.AuthorizeAsync
aufgerufen wird. Diese statische Methode erhält Folgendes:- Der Clientschlüssel (oder ein Stream zum Clientschlüssel).
- Die erforderlichen Bereiche.
- Die Nutzer-ID.
- Das Abbruchtoken zum Abbrechen eines Vorgangs.
- Optionaler Datenspeicher. Wenn der Datenspeicher nicht angegeben ist, ist standardmäßig ein
FileDataStore
mit einem standardmäßigenGoogle.Apis.Auth
-Ordner festgelegt. Der Ordner wird inEnvironment.SpecialFolder.ApplicationData
erstellt.
-
Die von dieser Methode zurückgegebene
UserCredential
wird mithilfe des Initializers alsHttpClientInitializer
auf derBooksService
festgelegt. Wie bereits erwähnt, implementiertUserCredential
einen HTTP-Client-Initialisierer. -
Im Beispielcode werden die Informationen zum Clientschlüssel aus einer Datei geladen. Sie können aber auch Folgendes tun:
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"));
Sehen Sie sich unser Beispiel für Bücher an.
Webanwendungen (ASP.NET Core 3)
Google APIs unterstützen OAuth 2.0 für Webserveranwendungen.
Die Bibliothek
Google.Apis.Auth.AspNetCore3 wird für die meisten Google-basierten OAuth 2.0-Szenarien in ASP.NET Core 3-Anwendungen empfohlen. Es wird ein Google-spezifischer OpenIdConnect
-Authentifizierungs-Handler implementiert. Es unterstützt die inkrementelle Authentifizierung und definiert eine injizierbare IGoogleAuthProvider
, um Google-Anmeldedaten anzugeben, die mit Google APIs verwendet werden können.
In diesem Abschnitt wird beschrieben, wie Sie Google.Apis.Auth.AspNetCore3 konfigurieren und verwenden. Der hier gezeigte Code basiert auf Google.Apis.Auth.AspNetCore3.IntegrationTests, einer voll funktionsfähigen Standard-ASP.NET Core 3-Anwendung.
Wenn Sie diese Dokumentation als Anleitung verwenden möchten, benötigen Sie eine eigene ASP.NET Core 3-Anwendung und müssen diese Schritte ausführen.
Vorbereitung
- Installieren Sie das Paket Google.Apis.Auth.AspNetCore3.
- Wir verwenden die Google Drive API. Daher müssen Sie auch das Paket Google.Apis.Drive.v3 installieren.
- Erstellen Sie ein Google Cloud-Projekt, falls Sie noch keines haben. Folgen Sie dazu dieser Anleitung. Das ist das Projekt, mit dem Ihre App identifiziert wird.
- Aktivieren Sie die Google Drive API. Folgen Sie dieser Anleitung, um APIs zu aktivieren.
-
Erstellen Sie Anmeldedaten für die Autorisierung, mit denen Ihre App bei Google identifiziert wird. Folgen Sie
dieser Anleitung, um Anmeldedaten für die Autorisierung zu erstellen und die Datei
client_secrets.json
herunterzuladen. Zwei Highlights:- Der Anmeldedatentyp muss Webanwendung sein.
- Für die Ausführung dieser App müssen Sie nur den Weiterleitungs-URI
https://localhost:5001/signin-oidc
hinzufügen.
Konfigurieren Sie Ihre Anwendung für die Verwendung von Google.Apis.Auth.AspNetCore3.
Google.Apis.Auth.AspNetCore3 ist in der Klasse Startup
oder einer ähnlichen Alternative konfiguriert, die Sie möglicherweise verwenden. Die folgenden Snippets stammen aus
Startup.cs
im Projekt „Google.Apis.Auth.AspNetCore3.IntegrationTests“.
-
Fügen Sie der Datei
Startup.cs
die folgende Anweisung hinzu:using Google.Apis.Auth.AspNetCore3;
-
Fügen Sie der Methode
Startup.ConfigureServices
den folgenden Code hinzu und ersetzen Sie die Platzhalter für die Client-ID und den Clientschlüssel durch die Werte in der Dateiclient_secrets.json
. Sie können diese Werte direkt aus der JSON-Datei laden oder auf andere sichere Weise speichern. In der MethodeClientInfo.Load
im Projekt „Google.Apis.Auth.AspNetCore3.IntegrationTests“ finden Sie ein Beispiel dafür, wie Sie diese Werte direkt aus der JSON-Datei laden.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}; }); }
-
Fügen Sie in der
Startup.Configure
-Methode der Pipeline ASP.NET Core 3-Authentifizierungs- und Autorisierungs-Middleware-Komponenten sowie HTTPS-Weiterleitungen hinzu:public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { ... app.UseHttpsRedirection(); ... app.UseAuthentication(); app.UseAuthorization(); ... }
Mit den Anmeldedaten des Nutzers in seinem Namen auf Google APIs zugreifen
Sie können Ihren Controllern jetzt Aktionsmethoden hinzufügen, für die die Nutzeranmeldedaten erforderlich sind, um im Namen des Nutzers auf Google APIs zuzugreifen. Im folgenden Snippet wird gezeigt, wie die Dateien im Google Drive-Konto des authentifizierten Nutzers aufgelistet werden. Achten Sie vor allem auf zwei Dinge:
-
Der Nutzer muss nicht nur authentifiziert sein, sondern auch den Bereich
https://www.googleapis.com/auth/drive.readonly
für Ihre Anwendung gewährt haben, den Sie mit dem AttributGoogleScopedAuthorize
angeben. -
Wir verwenden den Standardmechanismus zur Abhängigkeitsinjektion von ASP.NET Core 3, um eine
IGoogleAuthProvider
zu empfangen, mit der wir die Anmeldedaten des Nutzers abrufen.
Der Code:
-
Fügen Sie Ihrem Controller zuerst die folgenden Anweisungen hinzu.
using Google.Apis.Auth.AspNetCore3; using Google.Apis.Auth.OAuth2; using Google.Apis.Drive.v3; using Google.Apis.Services;
-
Fügen Sie die Controller-Aktion wie unten gezeigt hinzu und verknüpfen Sie sie mit einer Ansicht, die ein
IList<string>
-Modell empfängt:/// <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); }
Das sind die Grundlagen. Im Projekt „Google.Apis.Auth.AspNetCore3.IntegrationTests“ finden Sie unter
HomeController.cs
Informationen dazu, wie Sie Folgendes erreichen:
- Nur Nutzerauthentifizierung, ohne bestimmte Bereiche
- Nutzer abmelden
- Inkrementelle Autorisierung mit Code Beachten Sie, dass im Beispiel die schrittweise Autorisierung mit Attributen zu sehen ist.
- Gewährte Bereiche prüfen
- Zugriffs- und Aktualisierungstokens prüfen
- Aktualisieren Sie das Zugriffstoken erzwungen. Sie müssen das nicht selbst tun, da Google.Apis.Auth.AspNetCore3 erkennt, ob das Zugriffstoken abgelaufen ist oder bald abläuft, und es automatisch aktualisiert.
Dienstkonto
Google APIs unterstützen auch Dienstkonten. Anders als bei einem Szenario, in dem eine Clientanwendung Zugriff auf die Daten eines Endnutzers anfordert, gewähren Dienstkonten Zugriff auf die Daten der Clientanwendung selbst.
Ihre Clientanwendung signiert die Anfrage für ein Zugriffstoken mit einem privaten Schlüssel, der aus der Google API Console heruntergeladen wurde. Nachdem Sie eine neue Client-ID erstellt haben, sollten Sie einen Anwendungstyp für das Dienstkonto auswählen. Anschließend können Sie den privaten Schlüssel herunterladen. Sehen Sie sich unser Beispiel für ein Dienstkonto mit der Google Plus API an.
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(); } } }
In diesem Beispiel wird eine ServiceAccountCredential
erstellt.
Die erforderlichen Bereiche sind festgelegt und es gibt einen Aufruf von FromCertificate
, über den der private Schlüssel aus der angegebenen X509Certificate2
geladen wird.
Wie in allen anderen Beispielen wird das Anmeldedatenobjekt als HttpClientInitializer
festgelegt.