OAuth 2.0

このドキュメントでは、OAuth 2.0 について説明します。 使用するタイミング、 クライアント ID の取得方法 .NET 用 Google API クライアント ライブラリでの使用方法について学びます。

OAuth 2.0 プロトコル

OAuth 2.0 は、Google API で使用される認証プロトコルです。 以下のリンクを読み、このプロトコルについてよく理解しておく必要があります。

クライアント ID とシークレットの取得

クライアント ID とシークレットは、Google API Console で取得できます。 クライアント ID にはさまざまな種類がありますが、 アプリケーションに適したタイプを取得してください。

で確認できます。 <ph type="x-smartling-placeholder">

以下の各コード スニペット(サービス アカウント 1 を除く)では、 クライアント シークレットを作成し、プロジェクトに client_secrets.json として保存します。

<ph type="x-smartling-placeholder">

認証情報

ユーザー認証情報

UserCredential アクセス トークンを使用して保護されたリソースにアクセスするためのスレッドセーフなヘルパークラスです。 アクセス トークンは通常、1 時間後に期限切れになります。 その後、使用しようとするとエラーが発生します。

UserCredential および AuthorizationCodeFlow 自動で「更新」が行われるのでつまり、このトークンから 発行します。 これは、有効期間の長い更新トークンを使用して行われます。このトークンは、 アクセス トークンを使用する場合、 access_type=offline パラメータを使用して認証を行います。

ほとんどのアプリケーションでは、ストレージ クラスを 認証情報のアクセス トークンと更新トークンを永続ストレージに格納します。 それ以外の場合は、エンドユーザーに 認証ページへのアクセスを 1 時間ごとに行う必要があります。 トークンは受信後 1 時間で期限切れになります。

アクセス トークンと更新トークンを保持するには、 独自の実装を提供できます IDataStore または、ライブラリで提供されている以下の実装のいずれかを使用できます。

  • FileDataStore 認証情報がファイル内に永続的に保持されることを保証します。

ServiceAccountCredential

ServiceAccountCredential UserCredential に似ていますが、目的が異なります。 Google OAuth 2.0 は、ウェブ アプリケーションと Google Cloud Storage の間のサーバー間インタラクションなどをサポートしています。 リクエスト元のアプリケーションが API にアクセスするには、自身の ID を証明する必要があり、エンドユーザーが関与する必要はありません。 ServiceAccountCredential には秘密鍵が格納されます。この秘密鍵は、新しいアクセス トークンを取得するためのリクエストに署名するために使用されます。

UserCredentialServiceAccountCredential はどちらも実装しています。 IConfigurableHttpClientInitializer これらをそれぞれ次のように登録できます。

  • 失敗したレスポンス ハンドラ、 HTTP 401 ステータス コードを受け取ったらトークンを更新します。
  • Authorization をインターセプトするインターセプタ 指定することもできます。

インストールしたアプリケーション

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();
            ...
        }
    }
}
  
  • このサンプルコードでは、次のように呼び出して新しい UserCredential インスタンスを作成しています。 GoogleWebAuthorizationBroker.AuthorizeAsync メソッドを使用します。 この静的メソッドでは、以下を取得します。

    • クライアント シークレット(またはクライアント シークレットへのストリーム)。
    • 必要なスコープ。
    • ユーザー ID。
    • オペレーションをキャンセルするためのキャンセル トークン。
    • オプションのデータストア。データストアが指定されていない場合、デフォルトは FileDataStore です。 デフォルトの Google.Apis.Auth フォルダに配置します。 フォルダは Environment.SpecialFolder.ApplicationData に作成されます。
  • このメソッドによって返される UserCredentialHttpClientInitializer として設定されます。 BooksService で(イニシャライザを使用)。 前述のように、UserCredentialHTTP クライアントイニシャライザ

  • 上記のサンプルコードでは、クライアント シークレットの情報がファイルから読み込まれているため、 次の操作も行えます。

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

書籍サンプルをご覧ください。

ウェブ アプリケーション(ASP.NET Core 3)

Google API のサポート <ph type="x-smartling-placeholder"></ph> ウェブサーバー アプリケーション用 OAuth 2.0

<ph type="x-smartling-placeholder"></ph> Google.Apis.Auth.AspNetCore3 は、ほとんどの Google ベースのアプリケーション ASP.NET Core 3 アプリケーションでの OAuth 2.0 シナリオ。Google 固有のポリシーを実装する OpenIdConnect 認証ハンドラ。増分認証をサポートし、 IGoogleAuthProvider: Google API で使用できる Google 認証情報を指定します。

このセクションでは、Google.Apis.Auth.AspNetCore3 を構成して使用する方法について説明します。表示されているコードは、 ここに示されているのは <ph type="x-smartling-placeholder"></ph> Google.Apis.Auth.AspNetCore3.IntegrationTests: 完全に機能する標準の ASP.NET Core 3 アプリケーション。

このチュートリアルをチュートリアルとして使用する場合は、独自の ASP.NET Core 3 アプリケーションをインストールする必要があります。また、前提条件としてこれらの手順を完了する必要があります。

前提条件

  • <ph type="x-smartling-placeholder"></ph> Google.Apis.Auth.AspNetCore3 パッケージをインストールします。
  • Google Drive API を使用しているため、 インストールして Google.Apis.Drive.v3 パッケージ化されています。
  • Google Cloud プロジェクトを作成します(まだ作成していない場合)。フォロー <ph type="x-smartling-placeholder"></ph> こちらの手順をご覧ください。アプリが識別されるプロジェクトになります。
  • 必ず Google Drive API を有効にしてください。API を有効にする手順は次のとおりです。 <ph type="x-smartling-placeholder"></ph> こちらの手順をご覧ください。
  • Google がアプリを識別するための認証情報を作成します。フォロー <ph type="x-smartling-placeholder"></ph> 認証情報を作成し、認証情報をダウンロードして client_secrets.json ファイル。2 つのハイライト: <ph type="x-smartling-placeholder">
      </ph>
    • 認証情報のウェブ アプリケーションである必要があります。
    • このアプリを実行する場合、追加する必要があるリダイレクト URI は https://localhost:5001/signin-oidc

Google.Apis.Auth.AspNetCore3 を使用するようにアプリケーションを構成する

Google.Apis.Auth.AspNetCore3 が Startup クラスなどで構成されている ご確認ください次のスニペットは <ph type="x-smartling-placeholder"></ph> Google.Apis.Auth.AspNetCore3.IntegrationTests プロジェクトの Startup.cs

  • 次の using ディレクティブを Startup.cs ファイルに追加します。
    using Google.Apis.Auth.AspNetCore3;
  • Startup.ConfigureServices メソッドに次のコードを追加します。 クライアント ID とクライアント シークレットのプレースホルダは、 client_secrets.json ファイル。これらの値は、JSON ファイルから直接読み込むことができます。 その他の安全な方法で保存することもできます。詳しくは、 <ph type="x-smartling-placeholder"></ph> Google.Apis.Auth.AspNetCore3.IntegrationTests の ClientInfo.Load メソッド 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};
            });
    }
          
  • Startup.Configure メソッドに、ASP.NET Core 3 認証を必ず追加してください。 認可ミドルウェア コンポーネントをパイプラインに追加し、HTTPS リダイレクトを
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        ...
        app.UseHttpsRedirection();
        ...
    
        app.UseAuthentication();
        app.UseAuthorization();
    
        ...
    }
          
    <ph type="x-smartling-placeholder">

ユーザーの認証情報を使用してユーザーの代わりに Google API にアクセスする

これで、ユーザー認証情報を必要とするアクション メソッドをコントローラに追加する準備が整いました。 Google API にアクセスすることを許可しています。次のスニペットは、 Google ドライブ アカウントに対する認証と認可が行われます。主に次の 2 点に留意してください。

  • ユーザーは認証されるだけでなく、ユーザーの認証に https://www.googleapis.com/auth/drive.readonly スコープをアプリケーションに付与し、 GoogleScopedAuthorize 属性で指定する必要があります。
  • ASP.NET Core 3 の標準の依存関係挿入メカニズムを使用して、 ユーザーの認証情報を取得するために使用する IGoogleAuthProvider

コード:

  • まず、次の using ディレクティブをコントローラに追加します。
    using Google.Apis.Auth.AspNetCore3;
    using Google.Apis.Auth.OAuth2;
    using Google.Apis.Drive.v3;
    using Google.Apis.Services;
          
  • コントローラ アクションを次のように追加します(また、シンプルなビューとともに追加します)。 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);
    }
          

以上が基本情報です。詳しくは、 <ph type="x-smartling-placeholder"></ph> Google.Apis.Auth.AspNetCore3.IntegrationTests プロジェクトの HomeController.cs 以下を達成する方法をご確認ください。

  • ユーザー認証のみ、特定のスコープなし
  • ログアウト機能
  • コードによる段階的な認可。上記のスニペットでは 認証に使用できます。
  • 現在付与されているスコープを調べる
  • アクセス トークンと更新トークンを調べる
  • アクセス トークンを強制的に更新します。この作業は自分で行う必要はありません。 Google.Apis.Auth.AspNetCore3 は、アクセス トークンが期限切れか、期限切れ間近かを検出します。 自動的に更新されます

サービス アカウント

Google API は、 サービス アカウント。 クライアント アプリケーションがエンドユーザーのデータへのアクセスをリクエストするシナリオとは異なり、 サービス アカウントを使用すると、クライアント アプリケーション独自のデータにアクセスできます。

クライアント アプリケーションが、ダウンロードした秘密鍵を使用してアクセス トークンのリクエストに署名する Google API Console から使用できます。 新しいクライアント ID を作成した後、[サービス アカウント] を選択します。 秘密鍵をダウンロードできます。 詳しくは、 <ph type="x-smartling-placeholder"></ph> 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();
        }
    }
}

上記のサンプルコードでは、 ServiceAccountCredential。 必要なスコープが設定され、FromCertificate が呼び出されています。 このメソッドは、指定された X509Certificate2 から秘密鍵を読み込みます。 他のすべてのサンプルコードと同様に、認証情報は HttpClientInitializer として設定されます。