サービスアカウントの認証手順


はじめに

概要

外部のプログラムからGoogleAPIでGoogleアカウントのリソースにアクセスするためには、GoogleのサービスアカウントでOAuth2の認証が必要です。

ここでは認証の手順について書いていきます。

必要なもの

・Googleアカウント
・Google API client Library(今回はpython)

認証の仕組み


サービスアカウントの秘密鍵でJWT(Json Web Token)を生成して、JWTでAPI用のトークンを取得します。

プロジェクトの選択or作成

google developer console
Developer consoleからプロジェクト選択or新規作成

使用するAPIの有効化

API Managerのライブラリから利用するAPIを選択し、有効にする。

サービスアカウント作成

サービスアカウントキーの作成

認証情報 ▷ 認証情報を作成 ▷ 「サービスアカウントキー」 ▷ 新しいサービスアカウント ▷ JSON ▷ 作成

※作成ボタンを押すと「秘密鍵を含むJSONファイル」が自動的にダウンロードされる。その後ダウンロード出来ないので注意。

クライアントIDの作成(管理者権限が必要な場合)

認証情報 ▷ サービスアカウントの管理 ▷ 作成したサービスアカウントの右端の点を押す ▷ 編集 ▷ Gsuiteドメイン全体の権限を委任するにチェック

クライアントIDが表示できるようになっていることを確認

サービスアカウントにドメイン全体の権限を委任

※管理者権限が必要な場合の手順です

管理コンソールにadminでログイン
セキュリティ→もっと見る→詳細設定→「API クライアント アクセスを管理する」

サービスアカウントの「クライアントID」、利用するAPIの「scope」を入力して承認。

(JWTのclaimに"sub":"user_email"の追加が必要。)

JWTの生成

作成したサービスアカウントの秘密鍵を用いてJWTを作成します。

$curl -d "grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion="ここにJWT" https://www.googleapis.com/oauth2/v4/token

{
  "access_token" : "ya29.Elo4BOPu_8xrvZdah28zt3dgrX-x87vdy_BbFVt07XEm83d1S6-uZHBOCyKJdafHwIdV3ZiVDRdqhP9TpE8Vzo6_QZeAofp_Z5rMK_uwf-q_h_yrNcgTccdgSkY",
  "expires_in" : 3600,
  "token_type" : "Bearer"
}
$curl -H 'Authorization: Bearer ya29.Elo4BNIcKX8SEqyTg7CwGrp32W75pUddHQJIvB_mtk31-qnuz8N8MGOkZjeOLykuch8ATNo2jfa-hHOpNOBFHVH7lUS8MRNTN6YQj_kpCN4afoZAH_TPimXxEbA'  https://www.googleapis.com/admin/directory/v1/users/[email protected] 

API client Library for python で実装する場合

client library のインストール

$ pip install --upgrade google-api-python-client

Successfully installed google-api-python-client-1.6.2 httplib2-0.10.3 oauth2client-4.1.2 pyasn1-0.2.3 pyasn1-modules-0.0.9 rsa-3.4.2 six-1.10.0 uritemplate-3.0.0  ⇦くっついてくるもの

コード

credentials.py
from oauth2client.service_account import ServiceAccountCredentials
from httplib2 import Http


scopes = ['https://www.googleapis.com/auth/admin.directory.user, https://www.googleapis.com/auth/admin.directory.orgunit']
credentials = ServiceAccountCredentials.from_json_keyfile_name('/tmp/googleapi/serviceaccount.json', scopes=scopes)
delegated_credentials = credentials.create_delegated('[email protected]')  # 権限を委任
http_auth = credentials.authorize(Http())

credentialsオブジェクトを生成することで資格情報が保持される。