In diesem Dokument wird beschrieben, wann und wie OAuth 2.0 verwendet wird, wie Client-IDs abgerufen werden und wie OAuth 2.0 mit der Google API-Clientbibliothek für .NET verwendet wird.
OAuth 2.0-Protokoll
OAuth 2.0 ist das Autorisierungsprotokoll, das von Google APIs verwendet wird. Machen Sie sich unter den folgenden Links mit dem Protokoll vertraut:
Client-IDs und Secrets abrufen
Sie können Client-IDs und Secrets in der Google API Console abrufen. Es gibt verschiedene Arten von Client-IDs. Achten Sie daher darauf, den richtigen Typ für Ihre Anwendung zu verwenden:
- Client-IDs von Webanwendungen
- Client-IDs der installierten Anwendung
- Dienstkonto-Client-IDs
Laden Sie in jedem der folgenden Code-Snippets (außer dem Dienstkonto 1) den Clientschlüssel herunter und speichern Sie ihn als client_secrets.json
in Ihrem Projekt.
Anmeldedaten
Nutzeranmeldedaten
UserCredential
ist eine Thread-sichere Hilfsklasse für die Verwendung eines Zugriffstokens für den Zugriff auf geschützte Ressourcen.
Ein Zugriffstoken läuft in der Regel nach einer Stunde ab. Nach dem Versuch, es zu verwenden, erhalten Sie eine Fehlermeldung.
UserCredential
und AuthorizationCodeFlow
sorgen dafür, dass das Token automatisch aktualisiert wird, was einfach 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-Vorgangs den Parameter access_type=offline
verwenden.
In den meisten Anwendungen empfiehlt es sich, das Zugriffstoken und das Aktualisierungstoken der Anmeldedaten im nichtflüchtigen Speicher zu speichern. Andernfalls müssen Sie dem Endnutzer jede Stunde eine Autorisierungsseite im Browser anzeigen, da das Zugriffstoken eine Stunde nach Erhalt abläuft.
Damit die Zugriffs- und Aktualisierungstokens dauerhaft bestehen, können Sie Ihre eigene Implementierung von IDataStore
oder eine der folgenden von der Bibliothek bereitgestellten Implementierungen verwenden:
-
FileDataStore
für .NET sorgt dafür, dass die Anmeldedaten in einer Datei persistent bleiben.
ServiceAccountCredential
ServiceAccountCredential
ähnelt UserCredential
, erfüllt jedoch einen anderen Zweck.
Google OAuth 2.0 unterstützt Interaktionen zwischen Servern, beispielsweise zwischen einer Webanwendung und Google Cloud Storage.
Die anfragende Anwendung muss ihre eigene Identität nachweisen, um Zugriff auf eine API zu erhalten, und 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
, sodass Sie jedes davon als registrieren können:
- Ein fehlgeschlagener Antwort-Handler. Daher wird das Token aktualisiert, wenn es den HTTP-Statuscode
401
empfängt. - Ein Interceptor, der den Header
Authorization
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 durch Aufrufen der Methode
GoogleWebAuthorizationBroker.AuthorizeAsync
eine neueUserCredential
-Instanz erstellt. Diese statische Methode ruft Folgendes ab:- Der Clientschlüssel (oder ein Stream zum Clientschlüssel).
- Die erforderlichen Bereiche.
- Die Nutzerkennung.
- Das Stornierungstoken zum Abbrechen eines Vorgangs.
- Ein optionaler Datenspeicher. Wenn der Datenspeicher nicht angegeben ist, ist der Standardwert ein
FileDataStore
mit einem StandardordnerGoogle.Apis.Auth
. Der Ordner wird inEnvironment.SpecialFolder.ApplicationData
erstellt.
-
Die von dieser Methode zurückgegebene
UserCredential
wird alsHttpClientInitializer
fürBooksService
festgelegt (unter Verwendung des Initialisierers). Wie oben erläutert, implementiertUserCredential
einen HTTP-Clientinitialisierer. -
Im Beispielcode oben werden die Clientschlüsselinformationen 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 unsere Leseprobe an.
Webanwendungen (ASP.NET Core 3)
Google APIs unterstützen OAuth 2.0 für Webserveranwendungen.
Google.Apis.Auth.AspNetCore3 ist die empfohlene Bibliothek für die Verwendung der meisten Google-basierten OAuth 2.0-Szenarien in ASP.NET Core 3-Anwendungen. Es implementiert einen Google-spezifischen Auth-Handler OpenIdConnect
. Er unterstützt die inkrementelle Authentifizierung und definiert ein injizierbares 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 ASP.NET Core 3-Standardanwendung.
Wenn Sie dieser Dokumentation als Tutorial folgen möchten, benötigen Sie eine eigene ASP.NET Core 3-Anwendung und müssen diese Schritte als Voraussetzung ausführen.
Voraussetzungen
- Installieren Sie das Paket Google.Apis.Auth.AspNetCore3.
- Da wir die Google Drive API verwenden, 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. Dies 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, mit denen Ihre App gegenüber Google identifiziert werden kann. 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 lauten.
- Zum Ausführen dieser Anwendung müssen Sie nur den Weiterleitungs-URI
https://localhost:5001/signin-oidc
hinzufügen.
Anwendung für die Verwendung von Google.Apis.Auth.AspNetCore3 konfigurieren
Google.Apis.Auth.AspNetCore3 ist in der Klasse Startup
oder einer ähnlichen Alternative konfiguriert, die Sie möglicherweise verwenden. Die folgenden Snippets werden aus
Startup.cs
im Projekt Google.Apis.Auth.AspNetCore3.IntegrationTests extrahiert.
-
Fügen Sie der Datei
Startup.cs
die folgende Nutzungsdirektive hinzu.using Google.Apis.Auth.AspNetCore3;
-
Fügen Sie in der Methode
Startup.ConfigureServices
den folgenden Code hinzu und ändern Sie die Platzhalter für Client-ID und Clientschlüssel durch die in der Dateiclient_secrets.json
enthaltenen Werte. Sie können diese Werte direkt aus der JSON-Datei laden oder auf eine andere sichere Weise speichern. In der MethodeClientInfo.Load
im Projekt Google.Apis.Auth.AspNetCore3.IntegrationTests finden Sie ein Beispiel zum Laden dieser Werte direkt aus der JSON-Datei.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 Methode
Startup.Configure
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(); ... }
Die Anmeldedaten des Nutzers verwenden, um in seinem Namen auf Google APIs zuzugreifen
Sie können jetzt Aktionsmethoden zu Ihren Controllern hinzufügen, die Nutzeranmeldedaten benötigen, um in ihrem Namen auf Google APIs zuzugreifen. Das folgende Snippet zeigt, wie die Dateien im Google Drive-Konto des authentifizierten Nutzers aufgelistet werden. Beachten Sie vor allem zwei Dinge:
-
Der Nutzer muss nicht nur authentifiziert sein, sondern Ihrer Anwendung auch den Bereich
https://www.googleapis.com/auth/drive.readonly
gewährt haben, den Sie über das AttributGoogleScopedAuthorize
angeben. -
Wir verwenden den Standardmechanismus für Abhängigkeitsinjektionen von ASP.NET Core 3, um ein
IGoogleAuthProvider
zu erhalten, mit dem wir die Anmeldedaten des Nutzers abrufen.
Der Code:
-
Füge zuerst die folgenden Nutzungsanweisungen deinem Controller 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 beschrieben hinzu (und ergänzen Sie sie mit einer einfachen 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); }
Und das sind die Grundlagen. Unter
HomeController.cs
aus dem Projekt „Google.Apis.Auth.AspNetCore3.IntegrationTests“ finden Sie Informationen dazu, wie Sie das erreichen können:
- Nur Nutzerauthentifizierung ohne bestimmte Bereiche
- Abmeldefunktion
- Inkrementelle Autorisierung über Code. Das obige Snippet zeigt die inkrementelle Autorisierung über Attribute.
- Aktuell gewährte Bereiche untersuchen
- Zugriffs- und Aktualisierungstokens prüfen
- Erzwingen Sie die Aktualisierung des Zugriffstokens. Sie müssen dies 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. Im Gegensatz zu dem Szenario, in dem eine Clientanwendung Zugriff auf die Daten eines Endnutzers anfordert, bieten Dienstkonten Zugriff auf die eigenen Daten der Clientanwendung.
Ihre Clientanwendung signiert die Anforderung eines Zugriffstokens mit einem privaten Schlüssel, der von der Google API Console heruntergeladen wurde. Nachdem Sie eine neue Client-ID erstellt haben, sollten Sie den Anwendungstyp „Dienstkonto“ auswählen. Anschließend können Sie den privaten Schlüssel herunterladen. Sehen Sie sich unser Dienstkonto-Beispiel 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(); } } }
Mit dem obigen Beispielcode wird ein ServiceAccountCredential
erstellt.
Die erforderlichen Bereiche sind festgelegt und es wird FromCertificate
aufgerufen, um den privaten Schlüssel aus der angegebenen X509Certificate2
zu laden.
Wie bei allen anderen Beispielcodes sind die Anmeldedaten auf HttpClientInitializer
festgelegt.