Google Cloud Identity Platformのテナント認証を無効にする方法と実装例
はじめに
以前、Google Cloud Identity Platform(以降Identity Platform)のマルチテナンシー構成におけるパスワードポリシーの設定と更新方法についての記事を書きました。
今回はテナント毎の認証を無効にする処理が必要となりましたのでその実装方法について紹介したいと思います。
Identity Platformやマルチテナンシーについては上記の記事で解説しましたので、そちらを参照してください。
テナント認証の無効化
テナントの認証はテナント作成時には有効になっています。
無効にすることで、テナントに属するユーザは認証ができなくなります。
再度有効にすることで、テナントに属するユーザは再び認証が可能となります。
コンソールでのテナント認証の無効化処理
以下のようにテナントの一覧にトグルがあり、これを切り替えることでテナントへの認証を無効にしたり有効に戻したりできます。
テナントの一覧
GoのSDKにおけるテナント認証の無効化処理
パスワードポリシーの記事でも触れましたが、
GoのSDKにはテナントの更新機能は存在していますが、更新対象が制限されています。
結論としてはSDKがないため、APIによるテナント更新処理を呼び出します。
以降では、実際にテナント認証の無効化をコード例踏まえて解説していきます。
APIを用いたテナント認証の無効化更新手順
手順と言えるほどでもないですが、下記のとおりです。
- アクセストークンを取得
- テナント更新のAPIを使用して認証無効の設定を更新
- アクセストークンを指定して、REST APIのテナント更新
これはGoogle Cloudの他のAPIでも同様になります。
1. アクセストークンを取得
GCPでの認証方法は様々あり、どれを使うのが良いか迷うことがありますが、
ユースケースによって適した認証方法を選択するためのフローチャートがドキュメントとして用意されていますので、参考にするとよいでしょう。
今回の場合、アクセストークンの取得はサービスアカウントを用いて行います。
2. テナント更新のAPIを使用して認証無効の設定を更新
以下がテナント更新APIの概要です。
項目 | 詳細 |
---|---|
エンドポイント | https://identitytoolkit.googleapis.com/v2/projects/プロジェクトID/tenants/テナントID |
メソッド | PATCH |
クエリパラメータ |
updateMask : string (FieldMask format) |
FieldMask | FieldMaskの詳細 |
リクエストボディ | Tenantのjson構造体 |
レスポンスボディ | リクエストと同様のTenant のjson構造体 |
- 認可範囲
次の OAuth スコープのいずれかが必要です。
https://www.googleapis.com/auth/identitytoolkit
https://www.googleapis.com/auth/firebase
https://www.googleapis.com/auth/cloud-platform
※APIを実行するためにはアクセストークン生成時にこれらのスコープを指定してトークンを生成する必要があります。
テナントの更新APIは更新したい値をボディに指定しますが、
それとは別に、updateMask
というキーのパラメータを指定する必要があります。
このパラメータは、FieldMask
という特別な形式であり、更新する値と対になっている必要があります。
簡単に言うと、更新対象を含むjsonをボディに指定し、FieldMask
ではjson内で更新したい値を.
で区切った階層表現で指定します。
FieldMask
についてはパスワードポリシーのブログで解説したので、割愛します。
テナント認証の無効化の設定パラメータはdisableAuth
です。
true
で認証を無効に、false
で認証を有効にできます。
テナント更新API
Goでの実装
1. アクセストークンを取得
サービスアカウントを使用してGoogle Cloud APIに認証するためのアクセストークンを取得します。
このトークンは、APIリクエストの認証ヘッダーに含める必要があります。
func (t *Tenant) getToken(ctx context.Context, tenantID string) (string, error) {
// 環境変数にサービスアカウントのcredentialsを保持しています。ファイルから読み込むのと同等
jsonKey := []byte(os.Getenv("FIREBASE_CREDENTIALS_JSON"))
// サービスアカウントを使用してアクセストークンを生成
conf, err := google.CredentialsFromJSON(ctx, jsonKey, "https://www.googleapis.com/auth/cloud-platform")
if err != nil {
return "", err
}
token, err := conf.TokenSource.Token()
if err != nil {
return "", err
}
return token.AccessToken, err
}
テナント更新APIでは下記です。
2. テナント更新のAPIを使用して認証無効の設定を更新
パラメータとボディを整形して、HTTPリクエストを送信します。
// 引数として、更新対象のテナントIDと、先ほど生成したアクセストークンを受け取っています。
func (t *Tenant) updateTenant(tenantID, token string) error {
projectID := os.Getenv("PROJECT_ID")
// Identity Toolkit APIのURLを動的に構築
url := fmt.Sprintf("https://identitytoolkit.googleapis.com/v2/projects/%s/tenants/%s?updateMask=disableAuth", projectID, tenantID)
// リクエストボディの作成
requestBody, err := json.Marshal(map[string]interface{}{
"disableAuth": true,
})
if err != nil {
return err
}
req, err := http.NewRequest(http.MethodPatch, url, bytes.NewBuffer(requestBody))
if err != nil {
return err
}
req.Header.Add("Authorization", "Bearer "+token)
req.Header.Add("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
respBody, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
fmt.Printf("Response: %s\n", string(respBody))
return nil
}
まとめ
Identity Platformの解説とマルチテナント構成でのテナント認証の無効化について解説しました。
前回紹介したパスワードポリシーの更新でベースとなる知識があったので、比較的簡単に実装できました。
コンソールで見た際の設定項目とAPIのパラメータ名のギャップがあり、該当するパラメータを探すのに手間取りました。
参考資料
Discussion