OAuth 2.0

Ten dokument opisuje protokół OAuth 2.0, Kiedy z niego korzystać, jak pozyskiwać identyfikatory klientów, i jak używać jej z biblioteką klienta interfejsu API Google dla języka .NET.

Protokół OAuth 2.0

OAuth 2.0 to protokół autoryzacji używany w interfejsach API Google. Aby zapoznać się z protokołem, przeczytaj te linki:

Uzyskiwanie identyfikatorów i obiektów tajnych klienta

Identyfikatory klientów i tajne klucze dostępu znajdziesz w konsoli interfejsów API Google. Istnieją różne typy identyfikatorów klientów, pamiętaj więc, aby pobrać właściwy typ dla swojej aplikacji:

.

W przypadku każdego z poniższych fragmentów kodu (z wyjątkiem konta usługi) musisz pobrać tajny klucz klienta i zapisać go w projekcie jako client_secrets.json.

Dane logowania

Dane logowania użytkownika

UserCredential to klasa pomocnicza z zabezpieczeniem w wątkach, która służy do uzyskiwania dostępu do chronionych zasobów za pomocą tokena dostępu. Token dostępu wygasa zwykle po godzinie, a jeśli spróbujesz go użyć, pojawi się błąd.

UserCredential oraz AuthorizationCodeFlow dba o automatyczne „odświeżanie” czyli po prostu nowy token dostępu. W tym celu korzysta się z trwałego tokena odświeżania, który otrzymujesz wraz z tokenu dostępu, jeśli używasz access_type=offline podczas przesyłania kodu autoryzacji.

W większości aplikacji zaleca się przechowywanie token dostępu danych logowania i token odświeżania w pamięci trwałej. W przeciwnym razie musisz przedstawić użytkownikowi stronę autoryzacji w przeglądarce co godzinę, ponieważ dostęp wygasa godzinę po jego otrzymaniu.

Aby mieć pewność, że tokeny dostępu i odświeżania zostaną zachowane, możesz udostępnić własną implementację IDataStore Możesz też skorzystać z jednej z poniższych implementacji udostępnianych przez bibliotekę:

  • FileDataStore W przypadku .NET gwarantuje, że dane logowania będą trwałe w pliku.

ServiceAccountCredential

ServiceAccountCredential jest podobny do UserCredential, ale ma inny cel. Protokół Google OAuth 2.0 obsługuje interakcje między serwerami, na przykład między aplikacją internetową a Google Cloud Storage. Aplikacja wysyłająca żądanie musi potwierdzić swoją tożsamość, aby uzyskać dostęp do interfejsu API. Nie musi to robić użytkownik końcowy. ServiceAccountCredential przechowuje klucz prywatny, który jest używany do podpisywania żądania uzyskania nowego tokena dostępu.

Implementacja w zakresie UserCredential i ServiceAccountCredential IConfigurableHttpClientInitializer. więc możesz zarejestrować każdy z nich jako:

  • moduł obsługi nieudanych odpowiedzi, więc token zostanie odświeżony, jeśli otrzyma kod stanu HTTP 401.
  • Urządzenie przechwytujące do przechwycenia Authorization do każdego żądania.

Zainstalowane aplikacje

Przykładowy kod za pomocą interfejsu 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();
            ...
        }
    }
}
  
  • W tym przykładowym kodzie tworzona jest nowa instancja UserCredential przez wywołanie metody Metoda GoogleWebAuthorizationBroker.AuthorizeAsync. Ta metoda statyczna uzyskuje następujące wyniki:

    • Tajny klucz klienta (lub strumień do tajnego klucza klienta).
    • Wymagane zakresy.
    • Identyfikator użytkownika.
    • Token anulowania służący do anulowania operacji.
    • Opcjonalny magazyn danych. Jeśli nie określono magazynu danych, domyślną wartością jest FileDataStore z domyślnym folderem Google.Apis.Auth. Folder zostanie utworzony w Environment.SpecialFolder.ApplicationData.
  • UserCredential zwracany przez tę metodę ma wartość HttpClientInitializer. na BooksService (przy użyciu inicjatora). Jak wyjaśniliśmy powyżej, UserCredential implementuje komponent Inicjator klienta HTTP.

  • Zwróć uwagę, że w powyższym przykładowym kodzie informacje o tajnym kluczu klienta są wczytywane z pliku ale możesz też wykonać te czynności:

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

Spójrz na naszą próbkę Książek.

Aplikacje internetowe (ASP.NET Core 3)

Obsługa interfejsów API Google OAuth 2.0 dla aplikacji serwera WWW

Biblioteka Google.Apis.Auth.AspNetCore3 jest zalecana w przypadku większości Scenariusze dotyczące protokołu OAuth 2.0 w aplikacjach ASP.NET Core 3. Implementuje on specyficzny dla Google Moduł obsługi uwierzytelniania OpenIdConnect. Obsługuje uwierzytelnianie przyrostowe i określa metodę wstrzykiwania IGoogleAuthProvider w celu podania danych logowania Google, których można używać w interfejsach API Google.

W tej sekcji opisano, jak skonfigurować usługę Google.Apis.Auth.AspNetCore3 i jak z niej korzystać. Wyświetlony kod na podstawie Google.Apis.Auth.AspNetCore3.IntegrationTests to w pełni działający, standardowy pakiet ASP.NET aplikacji Core 3.

Jeśli chcesz korzystać z tej dokumentacji jako samouczka, musisz mieć własny ASP.NET Core 3 oraz wykonanie tych czynności jako wymagania wstępne.

Wymagania wstępne

  • Zainstaluj Google.Apis.Auth.AspNetCore3.
  • Używamy interfejsu Google Drive API, więc musisz też zainstalować Google.Apis.Drive.v3 pakietu SDK.
  • Utwórz projekt Google Cloud, jeśli jeszcze go nie masz. Obserwuj te instrukcje. Będzie to projekt, z którym identyfikowana jest Twoja aplikacja.
  • Pamiętaj, aby włączyć interfejs Google Drive API. Aby włączyć interfejsy API, wykonaj te instrukcje.
  • Utwórz dane uwierzytelniające, które posłużą Google do identyfikacji Twojej aplikacji. Obserwuj te instrukcje tworzenia danych uwierzytelniających i pobrania client_secrets.json. Co warto wiedzieć:
    • Zwróć uwagę, że dane logowania musi być typem Aplikacja internetowa.
    • Jedyny identyfikator URI przekierowania, który musisz dodać, by uruchomić tę aplikację, to https://localhost:5001/signin-oidc

Skonfiguruj swoją aplikację do korzystania z Google.Apis.Auth.AspNetCore3

Parametr Google.Apis.Auth.AspNetCore3 jest skonfigurowany w klasie Startup lub podobnej której może używać ciekawka alternatywna. Następujące fragmenty są wyodrębniane z: Startup.cs w projekcie Google.Apis.Auth.AspNetCore3.IntegrationTests.

  • Dodaj do pliku Startup.cs tę dyrektywę za pomocą polecenia using.
    using Google.Apis.Auth.AspNetCore3;
  • W metodzie Startup.ConfigureServices dodaj poniższy kod, zmieniając Zmienne Client-ID i Client Secret z wartościami podanymi w polach client_secrets.json. Możesz wczytać te wartości bezpośrednio z pliku JSON lub przechowywać je w jakikolwiek inny bezpieczny sposób. Zwróć uwagę na: ClientInfo.Load w Google.Apis.Auth.AspNetCore3.IntegrationTests , w którym znajdziesz przykład wczytywania tych wartości bezpośrednio z pliku 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};
            });
    }
          
  • W metodzie Startup.Configure dodaj uwierzytelnianie ASP.NET Core 3 komponentów oprogramowania pośredniczącego do autoryzacji i przekierowań HTTPS, a także:
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ...
        app.UseHttpsRedirection();
        ...
    
        app.UseAuthentication();
        app.UseAuthorization();
    
        ...
    }
          

Używanie danych logowania użytkownika do uzyskiwania dostępu do interfejsów API Google w jego imieniu

Możesz teraz dodać do kontrolerów metody działań, które wymagają danych logowania użytkownika do uzyskać dostęp do interfejsów API Google w ich imieniu. Ten fragment kodu pokazuje, jak wyświetlić listę plików w konta Dysku Google uwierzytelnionego użytkownika. Zwróć uwagę przede wszystkim na 2 rzeczy:

  • Użytkownik nie tylko musi być uwierzytelniony, ale też musi https://www.googleapis.com/auth/drive.readonly zakres do Twojej aplikacji, który podasz za pomocą atrybutu GoogleScopedAuthorize.
  • Używamy standardowego mechanizmu wstrzykiwania zależności ASP.NET Core 3 do IGoogleAuthProvider, za pomocą których uzyskujemy dane logowania użytkownika.

Kod:

  • Najpierw dodaj do kontrolera te instrukcje za pomocą instrukcji.
    using Google.Apis.Auth.AspNetCore3;
    using Google.Apis.Auth.OAuth2;
    using Google.Apis.Drive.v3;
    using Google.Apis.Services;
          
  • Dodaj działanie kontrolera w podany niżej sposób (i dodaj do niego prosty widok). który odbiera model 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);
    }
          

To podstawy. Rzuć okiem na HomeController.cs z projektu Google.Apis.Auth.AspNetCore3.IntegrationTests aby dowiedzieć się, jak osiągnąć:

  • Tylko uwierzytelnianie użytkownika, bez konkretnych zakresów
  • Funkcja wylogowania
  • Autoryzacja przyrostowa za pomocą kodu. Zwróć uwagę, że ten fragment kodu generuje przyrostowe autoryzacją za pomocą atrybutów.
  • Sprawdzanie obecnie przyznanych zakresów
  • Badanie tokenów dostępu i odświeżania
  • Wymuś odświeżenie tokena dostępu. Zwróć uwagę, że nie musisz tego robić samodzielnie, ponieważ Google.Apis.Auth.AspNetCore3 wykryje, czy token dostępu nie stracił już ważności po czym automatycznie go odświeży.

Konto usługi

Interfejsy API Google również obsługują Konta usługi. W przeciwieństwie do sytuacji, w której aplikacja kliencka prosi o dostęp do danych użytkownika, konta usługi zapewniają dostęp do danych własnych aplikacji klienckiej.

Twoja aplikacja kliencka podpisuje żądanie o token dostępu przy użyciu pobranego klucza prywatnego. z Konsoli interfejsów API Google. Po utworzeniu nowego identyfikatora klienta wybierz „Konto usługi” typu aplikacji i pobierz klucz prywatny. Zapoznaj się z naszą przykład konta usługi za pomocą interfejsu Google Plus API.

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

Powyższy przykładowy kod tworzy ServiceAccountCredential Ustawiono wymagane zakresy i zostało wysłane wywołanie do funkcji FromCertificate, który wczytuje klucz prywatny z podanego X509Certificate2. Tak jak we wszystkich innych przykładach kodu, dane logowania są ustawione jako HttpClientInitializer.