サーバー間のアプリケーションで OAuth 2.0 を使う

このページは、 Using OAuth 2.0 for Server to Server Applications を翻訳したものです。原文は HTML のコメントとして残してあります。 なお、対象のプログラミング言語は Python 部分のみの翻訳です。

目次

Google OAuth 2.0 では、Web アプリケーション(以下アプリと略記)と Google のサービスなど、サーバー間での対話処理をサポートしています。 このシナリオでは、サービスアカウントが必要になります。これは、 エンドユーザー個人の代わりに、あなたのアプリに従属するアカウントです。 あなたのアプリはサービスアカウントに代わって Google API への呼び出しを行いますので、 ユーザーが直接関わることはありません。このシナリオは、しばしば "two-legged OAuth" または "2LO." と呼ばれます。(これに関連する用語として "three-legged OAuth" があります。 この場合は、あなたのアプリはエンドユーザーに代わって Google API の呼び出しを行いますが、 その際ユーザーの同意が必要になる場合があります。)

通常、アプリがユーザーデータではなくアプリ自身のデータ取得のために Google API を使う場合、アプリはサービスアカウントを使います。たとえば、データの永続的な保持のために Google Cloud Datastore を使うアプリであれば、Google Cloud Datastore API への呼び出しをする際、サービスアカウントを使って認証を行います。

たとえば、もしあなたが Google Apps ドメインを保持していて Google Apps for Work を使っている場合、 Google Apps ドメインの管理者は、その Apps ドメインにおいて、 ユーザーの代わりにアプリを認可してユーザデータへのアクセスを行わせることが可能です。 たとえばあるアプリが Google Calendar API を使って Google Apps ドメインの全ユーザーのカレンダーにイベントを追加する場合、そのアプリは ユーザーの代わりにサービスアカウントを使って Google Calendar API にアクセスします。 ドメイン内のユーザーの代わりにサービスアカウントを認可してデータにアクセスさせることは、 サービスアカウントに対して『ドメイン全体の権限を移譲する』と呼ばれることがあります。

注意:Google Apps Marketplace を使ってあなたのドメインにアプリをインストールする場合、 そのアプリに対して要求される権限は自動的に付与されます。 そのアプリが使うサービスアカウントを手動で認可する必要はありません。
注意:Google Apps ドメインで動かしたアプリでもサービスアカウントを利用できますが、 サービスアカウントは Google Apps のアカウントではないため Google Apps の管理者が策定したドメインポリシーの支配を受けません。たとえば、Google Apps の管理者コンソールにおいて、エンドユーザーがドメイン外とドキュメントを 共有できるようなポリシー設定をしたとしても、それはサービスアカウントには適用されません。

この文書では、アプリが Google API クライアントライブラリ(推奨)または HTTP のいずれかを使って、どのようにしてサーバ間の OAuth 2.0 フローを実現しているのかを紹介しています。

概要

サーバ間の対話処理をサポートするにあたり、まずは Developers Console で、 あなたのプロジェクトの中にサービスアカウントを作成してください。 次に Google Apps ドメインでユーザーデータにアクセスしたい場合、 ドメイン全体のアクセス権をサービスアカウントに移譲します。

その後、あなたのアプリはサービスアカウントの資格情報を使って認可された API コールを行う準備を行い、OAuth 2.0 認可サーバからのアクセストークンを要求します。

最後に、あなたのアプリはアクセストークンを使って Google API をコールします。

推奨事項:これらのタスクを実行するにあたり、あなたのアプリには、 利用中のプログラミング言語に合った Google API クライアントライブラリを使うか、 または HTTP を使って OAuth 2.0 のシステムと直にやり取りを行うかという2つの選択肢があります。 しかしながら、サーバ間の認証のやり取りには、アプリが JSON Web Token (JWT) を生成し、 さらにそれを暗号化して署名する必要があるため、深刻なエラーが起きやすく、 あなたのアプリに対して重大なセキュリティの脅威を与えることになりかねません。

このような理由により、私達はあなたのアプリのコードから暗号化部分を抽象化する、 Google API クライアントライブラリ等のライブラリの利用を強く推奨します。

サービスアカウントを作成する

サービスアカウントの資格情報には、 自動生成されたユニークなメールアドレスとクライアントID、 および少なくとも一組の秘密鍵/公開鍵のペアが入っています。

あなたのアプリを Google App Engine 上で動かす場合は、 プロジェクトを作成する際にサービスアカウントが自動的に作成されます。

あなたのアプリを Google Compute Engine 上で動かす場合も、 プロジェクトを作成する際にサービスアカウントが自動的に作成されます。 ただし Google Compute Engine のインスタンスを作成する際、 あなたのアプリがアクセスする必要のあるスコープを指定する必要があります。 詳細は Preparing an instance to use service accountsを参照してください。

あなたのアプリを Google App Engine / Google Compute Engine のいずれでも動かさない場合は、これらの資格情報を Google Developers Console で取得しなければなりません。資格情報を生成したり、 生成済みの公開鍵を参照したりするには以下の手順を実行してください。:

  1. 認証ページを開きます。
  2. 以下の手順により新しいサービスアカウントを作成します。: これであなたの新しい秘密鍵/公開鍵のペアが生成され、あなたのマシンにダウンロードされます。 これはこのキーの唯一のコピーとして提供されます。 あなたはこれを安全な手段を使って保管する責任があります。

あなたはいつでも Developers Console に戻って来て、クライアントIDやメールアドレスや公開鍵の指紋を閲覧したり、 追加で秘密鍵/公開鍵のペアを作成したりできます。 Developers Console におけるサービスアカウントの資格情報に関する詳細は、 Developers Console ヘルプファイルの サービスアカウントを参照してください。

サービスアカウントのメールアドレスに注意して、サービスアカウントの P12 秘密鍵ファイルをあなたのアプリからアクセスできるところに保存してください。 あなたのアプリが認可された API をコールする際、そのファイルが必要になります。

注意:秘密鍵ファイルは開発環境と本番環境双方において、 安全に管理しなければなりません。Google は秘密鍵のコピーを保存しておらず、 公開鍵の方しか保持していません。

ドメイン全体の権限をサービスアカウントに移譲する

あなたのアプリからユーザーデータにアクセスする場合、 あなたが作成したサービスアカウントは、あなたがアクセスしたいと思っている Google Apps ドメインのユーザーデータへのアクセスが許可されていなければなりません。

以下の手順は、Google Apps ドメインの管理者によって実行されなければなりません。:

  1. Google Apps ドメインの管理コンソール を開きます。
  2. コントロール一覧からセキュリティを開きます。 セキュリティが見当たらない場合は、 ページの最下段にある灰色バーのその他の設定を開いて、 その中からセキュリティを選択してください。コントロールが見つからない場合は、 本当にそのドメインの管理者としてログインしているかどうかを確認してください。
  3. もっと見るを選択し、詳細設定を開きます。
  4. 認証APIクライアントアクセスを管理するを選びます。
  5. クライアント名の項目でサービスアカウントのクライアントIDを入力します。
  6. 1つ以上の API の範囲項目で、 あなたのアプリがアクセスを許可されるべきスコープのリストを入力します。 たとえば、あなたのアプリが Google Drive API と the Google Calendar API についてドメイン全体のアクセス権が必要であれば、
    https://www.googleapis.com/auth/drive,
    https://www.googleapis.com/auth/calendar
    と入力します。
  7. 承認をクリックします。

これであなたのアプリはあなたのドメインの中で(”なりすまし”ユーザーとして) API をコールするための権限を持つことができました。認可済み API コールを行う準備をする際は、なりすます対象のユーザーを指定します。

認可済み API コールの準備を行う

Python

Developers Console からクライアントのメールアドレスと秘密鍵を取得したら、 Google APIs Client Library for Pythonを使って以下の手順を実行します。:

  1. サービスアカウントの資格情報、 およびあなたのアプリがアクセスを必要とするスコープから、 資格情報オブジェクトを作成します。以下に例を示します。:
    プラットフォーム コードのサンプル
    Google App Engine
    from oauth2client.appengine import AppAssertionCredentials
    
    credentials = AppAssertionCredentials(
        'https://www.googleapis.com/auth/sqlservice.admin')
    注意:Google App Engine もしくは Google Compute Engine 上で動かす場合、 アプリ内のAppAssertionCredentials資格情報オブジェクトのみが利用できます。 それ以外の環境 - たとえばローカルのテスト環境など - で動かす場合、 あなたのアプリはそのことを検知して、別の資格情報メカニズムを使う必要があります。 (その他を参照してください)。
    Google Compute Engine
    from oauth2client.gce import AppAssertionCredentials
    
    credentials = AppAssertionCredentials(
        'https://www.googleapis.com/auth/sqlservice.admin')
    注意:Google App Engine もしくは Google Compute Engine 上で動かす場合、 アプリ内のAppAssertionCredentials資格情報オブジェクトのみが利用できます。 それ以外の環境 - たとえばローカルのテスト環境など - で動かす場合、 あなたのアプリはそのことを検知して、別の資格情報メカニズムを使う必要があります。 (その他を参照してください)。 アプリのデフォルトの資格証明を使うことで、この手順を簡略化することもできます。
    その他
    from oauth2client.client import SignedJwtAssertionCredentials
    
    client_email = '123456789000-abc123def456@developer.gserviceaccount.com'
    with open("MyProject.p12") as f:
      private_key = f.read()
    
    credentials = SignedJwtAssertionCredentials(client_email, private_key,
        'https://www.googleapis.com/auth/sqlservice.admin')

    サービスアカウントに対してドメイン全体のアクセス権を移譲してユーザアカウントを詐称したい場合、 Credentialsオブジェクトを生成する時に、 subパラメーターにユーザアカウントのメールアドレスを指定してください。 以下に例を示します。:

    credentials = SignedJwtAssertionCredentials(client_email, private_key,
        'https://www.googleapis.com/auth/sqlservice.admin',
        sub='user@example.org')
  2. Credentialsオブジェクトのauthorizeメソッドを使って、 必要な資格情報ヘッダをhttplib2.Http インスタンスが生成するすべてのリクエストに適用するようにします。以下に例を示します。:
    from httplib2 import Http
    
    http_auth = credentials.authorize(Http())

あなたのアプリで認可済みのHttpオブジェクトを使って Google API をコールします。

Google API をコールする

Python

以下の手順により、認可済みのHttpオブジェクトを使って Google API をコールします。

  1. コールしたい API に使うサービスオブジェクトをビルドします。 build関数をコールしてサービスオブジェクトをビルドしますが、 その際その API の名前と、認可済みのHttpオブジェクトを指定します。 以下に Cloud SQL Administration API バージョン 1beta3 をコールする例を示します。:
    from apiclient.discovery import build
    
    sqladmin = build('sqladmin', 'v1beta3', http=http_auth)
    
  2. interface provided by the service objectを使って API サービスへのリクエストを作成します。たとえば、exciting-example-123 プロジェクトで Cloud SQL databases のインスタンスの一覧を取得する場合は以下のようになります。:
    response = sqladmin.instances().list(project='exciting-example-123').execute()
    

特に記載のない限り、このページのコンテンツは クリエイティブ・コモンズの表示 3.0 ライセンス により使用許諾されます。サンプル コードは Apache 2.0 ライセンス (リンク先は英語)により使用許諾されます。詳しくは、Google のサイトに関するポリシーをご覧ください。

最終更新日: 8月 18, 2015

Go previous