こんにちは、SWX3人目の熊谷(悠)です。
Web UIが無く(≒ユーザーに承認させる画面が出せない)、API キーでの認証にもしたくなかったので、サービスアカウントが使いたい。
ただ、サービスアカウントを使った実装方法はあまり無かったので認証情報の作成手順と併せてまとめました。
PythonでGoogleグループからメンバーのメールアドレス一覧を取得する例は末項に載せていますのでそちらをご参照ください。
前提
設定は全て、組織の管理者ユーザー※にて作業しています。
※「ユーザー」>「管理者ロールと権限」にて、全ての組織部門の「特権管理者(Google Apps Administrator Seed Role)」ロールを割り当て済みユーザー
※権限を持ち合わせていないユーザーでも「ドメイン全体の委任を管理」以外の設定は可能です。
設定手順
ブラウザにてGoogle Cloud Platformへアクセスし、ログイン
プロジェクト作成
画面上部プラットフォームバーのプロジェクト選択からウィンドウを開き、「新しいプロジェクト」ボタンをクリック
必要な情報を入力し、「作成」ボタンをクリック
- プロジェクト名:任意
- 組織:任意のプロジェクトを関連付けるGoogle WorkSpace組織
- 場所:任意の親組織またはフォルダ
プロジェクトが作成されたら、プロジェクトを選択
ダッシュボード画面で作成したプロジェクト情報が表示されている事を確認
Admin SDK有効化
画面上部プラットフォームバーからナビゲーションメニューを開き、「API とサービス」>「ライブラリ」を選択
「Admin SDK API」を検索し、表示されたカードをクリック
「有効にする」ボタンをクリック
サービスアカウント作成
サイドバーの「認証情報」を選択
画面上部の「+認証情報を作成」ボタンをクリックし、「サービスアカウント」を選択
サービス アカウントの詳細
必要な情報を入力し、「作成して続行」ボタンをクリック
- サービスアカウント名: 任意の値
- サービスアカウントID: 任意の値(サービスアカウント名から自動入力される)
このサービス アカウントにプロジェクトへのアクセスを許可する
デフォルト値のまま「続行」ボタンをクリック
ユーザーにこのサービス アカウントへのアクセスを許可
デフォルト値のまま「完了」ボタンをクリック
鍵作成
作成されたサービスアカウント右部操作列の編集アイコン(サービスアカウントを編集)をクリック
「キー」タブを開く
「鍵を追加」ボタンをクリックし、「新しい鍵を作成」を選択
キーのタイプ: JSON を選択したまま「作成」ボタンをクリック
ダウンロードされる秘密鍵ファイルを大切に保管
※追加作成はできても同じ鍵の復元は出来ません。
※鍵ファイルはAPI実行に必要です。
ID確認
(作成されたサービスアカウントを開き、)「詳細」タブを開く
「一意の ID」の値をメモ
権限設定
※本項のみログインしているユーザーに組織の管理者権限が必要です。
サイドバーのメインメニューから「セキュリティ」>「アクセスとデータ管理」>「API の制御」を開く 画面下部のドメイン全体の委任ブロック内の「ドメイン全体の委任を管理」ボタンをクリック
「新しく追加」ボタンをクリックし、表示されたウィンドウで下記を入力
- クライアント ID:前項にてメモしたサービスアカウントの「一意の ID」
- OAuthスコープ:API Reference を参考に、実行したいAPIに必要な権限の「OAuthスコープ」
「承認」ボタンをクリック
実装
鍵作成でダウンロードした秘密鍵ファイルは下記のようなJSONデータになっています。
(鍵ファイルとしてはあまり見ない形ですが、このファイルはこのままでAPI実行時に使用します。)
{ "type": "service_account", "project_id": "test-project-341704", "private_key_id": "57f58802123c3edc9147c8a9e7c4fd09e77c85d2", "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCq1ifZJ8+GPLlx\n/Ju5eaYnusu4rAganlIZYek1PTd6m5ZkODpZA7HkohgxFWroE+BL8AxBtTJVhiqR\neYspblT09L5ki2/iMNVOIqvlhfLdXbkZzFTwlYHPyCUICcGgkDeBoRp+WAU7gett\n0vS0P1eg5ypQrAJfW9d1qRYx7AAP84JdCcUn96ce9hRzRp2+GMXVsdoi9CZVHupj\n5B5PGJsFm2Q0Jj2Kri7GQXq4ZFJ6ri5D2fVUjrBFnniOrtIUDTXHb01RPVabBSPR\n9KpYiODtUosA2aZjThSv6pL5C8Hvuxij+cCwizyRFOFri7I+EDRIN66656ZOGuoN\nM3hhZV9zAgMBAAECggEACmh/cgQHvo/Jjpp2KbUx0dQtdZle6bGWopRBX0HVCk5w\nubdmmqYWewMDLU5hk9/OImJEJOazY9wyO2hnzu+OvoPWFmMbvxtRi5qiKsWKl+u4\ntiEpqvoOOB4OCjDUpVcpV+em/maXdFovK/hBJLrX4xDMqRQ2EDVW5p/B12YQw5rH\nqkrMqMtoKYd4tKcoYnx+48WupDk/I+ZuxFeVe60KXTCZJ+ckuHLzY3E0yqoue7ql\ncw9y1YSe5tK1QyfXP8t5l0u2Fkoesb7cyIbfeCaybTsUZW4JXxN7BRwJwhrJwqR+\nyBMDsGFd29QAgi3FSvFXhjJQ/VIR5rTCw4dCMgkpRQKBgQDtL6R1SWl9sfTJuZFy\n7olWaq6wvaYKAzFEPW9tnj77G52xK/SQz4YJdj1yWjARnI5htf7xIsqsO9P8Dmd0\nfYOLNnA5rMsUOST5C9Ek5CkzlS32EBlEcxctwFffERz1aGhWH/rD34TZ7V8U/3Ob\nkYVanObQ/T4E4doQ+RW9foohNQKBgQC4YzQLaxuIaKPjMTKCnhe3mjF+NGDCQMaQ\nrI3sceiLg5L72aHGP5TJW0PGsx7OvbNHtpCNqfyv8jGxNw/w/l8x8/WJE6KECEkS\nWF16RPoUUwBQztvIpGbhljk67WWt9000oCRzrAIuCzQUlwAGD6rw9S/u1U61w0Ft\nznmqxkJ7BwKBgFKio6idUByT0JYriepCAyWCUX2heAkptEg0AYRvPSGEjcU8ajO9\nqZRIVrYth8vLAKw4TT9UAMqq+Xs6xX6HcDojWEwvz9Wh5uZwy2zWsD+nYLX97rJI\nCoKeRFqXCLbjjl5bO/HcQRvwII1fRrbvp0dfnOc5I89tpJz/OzzPBm71AoGAUpCJ\nY3uIjqJckIUdGwPzltFCzEJj+VfMEkhMvb675Rog9itjpXa0LJS0InYnTIB3/VoS\nlUdxgPn70adsIPzzrxKOJUG7Zgo5EzjUjsaSubfj2q/xIfD+VOlf88qvKV09haAT\nWlVs+qsiSdx7tDsbzl3cItP9NMLD74l/TYsNhc39QT3u7iE6I67rAmaD0CgYEAqb\nPKUYiQ7z2RYGsNXoORO5GjynSxFMe8XtrabG7b9bWTKQj2iUfuXX2DFGj7jVZZnf\nKG6IJFrtr8/4XBTbGrRdk3BURHBk0krD/ZbqGfqqbQHJ9H8YzM8GuFDNSB8Jp9KX\n4rCbL+l2Ema8h4MUvypIWGk=\n-----END PRIVATE KEY-----\n", "client_email": "test-service-account@test-project-341704.iam.gserviceaccount.com", "client_id": "117010293622626332958", "auth_uri": "https://accounts.google.com/o/oauth2/auth", "token_uri": "https://oauth2.googleapis.com/token", "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/test-service-account%40test-project-341704.iam.gserviceaccount.com" }
Googleグループからメンバーのメールアドレス一覧を取得してみます。
from google.oauth2 import service_account from googleapiclient.discovery import build if __name__ == '__main__': # 「ドメイン全体の委任を管理」でも指定した、実行したいAPIに必要な権限の「OAuthスコープ」をカンマ区切りで指定します。 SCOPES = ['https://www.googleapis.com/auth/admin.directory.group.member.readonly'] # 第一引数は秘密鍵ファイルを読み込んだjsonオブジェクトでも大丈夫です。 credentials = service_account.Credentials.from_service_account_file('test-project-341704-57f58802123c.json', scopes=SCOPES) # サービスアカウントから管理者ユーザーへの委任を実施しています。組織の管理者ユーザーのメールアドレスを指定してください。 delegated_credentials = credentials.with_subject('test@example.com') service = build('admin', 'directory_v1', credentials=delegated_credentials) # API Reference を参考に、serviceに対して必要なAPI(の関数)を実行してください。 response = service.members().list(groupKey='hoge-ml@example.com').execute() member_email_list = [member.get('email') for member in response.get('members', [{"email": "No Members"}])] print(f'メンバーメールアドレスリスト:{member_email_list}') pass
$ python get-members-list.py メンバーメールアドレスリスト:['menber-01@example.com','menber-02@example.com']
参考
設定
Using OAuth 2.0 to Access Google APIs | Google Identity | Google Developers
Using OAuth 2.0 for Server to Server Applications | Google Identity | Google Developers
Create access credentials | Google Workspace for Developers | Google Developers
実装
Using OAuth 2.0 for Server to Server Applications | Google Identity | Google Developers
Python Quickstart | Directory API | Google Developers
Method: members.list | Directory API | Google Developers
oauth2client.service_account module — oauth2client 4.1.2 documentation
google-api-python-client/oauth.md at main · googleapis/google-api-python-client · GitHub
google_auth_oauthlib.flow module — google-auth-oauthlib 0.4.1 documentation
google.oauth2.service_account module — google-auth 1.30.0 documentation