Google Apps ScriptからAzure Entra IDのユーザ情報読み書き【GAS】

Microsoft Azure ADことEntra IDは導入してIdPとして使ってるけれど、Google Workspaceを使っているという場合、プロビジョニングで自動連携してるケースがあります(Entra側にユーザ追加や更新すると自動でGWS側も反映する)。その際に組織部門の値をもって同期するとユーザの組織部門配置を書き換えが可能です。

しかし、ユーザ数が多い場合や定期異動、転勤等で配置転換が起きるとEntra ID側のプロパティをいちいち開いて手修正なんてやってられません。そこでこれをスプレッドシート上のデータを元に一括でGraph APIを利用してEntra IDのユーザデータを読み書きを出来るようにしてみました。

今回利用するスプレッドシート

利用する為には事前準備が必要です。また、今回はFAX番号に対してGWS側のOrgUnitPathの値を格納するというシーンを想定しています。これは過去記事の以下のエントリーにて、ユーザプロパティの値をもって同期を掛けるというシーンで使えるものになります。

ただ、汎用的なコードですので、コードを色々書き換えれば、例えば人事管理システムからデータを引き抜いて、それをEntra ID側に反映するなんて使い方も出来るでしょう。

Entra IDとGoogle Workspaceのメンバーを同期させる方法 - Provisioning編

事前準備

GAS側の準備

ライブラリの追加

以下の手順でOAuth2 for Apps Scriptライブラリを追加しましょう。

  1. スクリプトエディタを開きます。
  2. 左サイドバーのライブラリの+をクリックします
  3. ライブラリを追加欄に「1B7FSrk5Zi6L1rSxxTDgDEUsPzlukDsi4KGuTMorsTQHhGBzBkMun4iDF」を追加します。
  4. 今回はバージョンは43を選択してみます。
  5. 保存ボタンを押して完了

図:OAuth2ライブラリの追加を行っておく

コールバックURLを作っておく

コールバックURLとは、認証を完了しAccess Tokenを取得したら戻るべきURLを指定するものです。これは、スクリプトIDをもとに作られているので、スクリプトIDを取得して組み立てます。

  1. スクリプトエディタの左サイドバーより、プロジェクトの設定を開く
  2. 情報の中にある「スクリプトID」をコピーする。
  3. https://script.google.com/macros/d/スクリプトID/usercallback として組み立てる。これがコールバックURLとなる。

このコールバックURLをAzure側の準備で利用します。

図:スクリプトIDを元に構築する

組織部門

今回はEntra ID側での値の反映までしか見ませんので参考情報ですが、Entra ID側に/GWSと/CIFという2つの値を格納する予定です。これは管理コンソールに於いてユーザの組織部門配置で利用する値で、OrgUnitPathに該当します。この値ですが、組織部門のルートが「/」から始まるので、その下の組織部門がGWSならば「/GWS」という値を格納する必要があります。

よって、利用する場合には上記のルールを把握して、Entra ID側の今回はFAX番号欄へと記入するのが目的です。(別にFAX番号でなくとも良いのですが)。

Azure側の準備

Azure側に入って、アプリを作成します。

  1. アプリの登録にて登録を開始する
  2. 新規登録をクリックする
  3. 名前を入力(今回はentraidmanと入力しました)、リダイレクトURIは「webを選択しhttps://script.google.com/macros/d/スクリプトID/usercallback」を入力
  4. 登録ボタンをクリックする
  5. 出てきた中で、「アプリケーション(クラと書かれているのがクライアントID」なので、このコードをメモしておく
  6. 左サイドバーより、「証明書とシークレット」をクリック
  7. 新しいクライアントシークレット」をクリックする
  8. 今回は6ヶ月の期限を選択するのでそれをクリック
  9. これで値に「クライアントシークレット」が生成されて手に入りました。このシークレットはこの時だけしか表示されないので、注意してください(シークレットIDではないので注意)
  10. つづけて、左サイドバーより「APIのアクセス許可」をクリックする
  11. Microsoft APIの中にある「Microsoft Graph」をクリックする。
  12. 委任されたアクセス許可」をクリックする
  13. デフォルトでUser.ReadがすでにONなので、今回はopenid、email、offline_access、User.ReadWrite.All、Directory.ReadWrite.Allを検索してONにしましょう。
  14. アクセス許可の追加をクリックする
  15. 追加出来たら、xxxxxに管理者の同意を与えますをクリックします。すると、状態が緑色になります。
  16. 次に左サイドバーより「認証」をクリック
  17. 暗黙の付与にて、「アクセストークン」にチェックを入れる
  18. サポートされているアカウントの種類に於いては、「マルチテナント」にしておきました。
  19. 保存をクリック
  20. 概要のエンドポイントをクリックすると、いろいろなエンドポイントURLが出る

図:Graphを選択する

図:アクセス権限付与した状態

図:認証の設定変更に注意

ソースコード

今回は、FAX番号の読み書きをするので利用するAPIはBetaであることに注意が必要です。取得しておいたアプリケーションIDやクライアントシークレット、Graph APIで許可したAPIのスコープ情報を記述する必要があります。

認証を行うコード

認証実行はstartoauthを叩くのですが、事前にウェブアプリケーションとしてデプロイしておく必要があります。

GAS側コード

Authorize.gsというファイルに記述しています。今回は便宜的にここの上部にアプリケーションIDや、クライアントシークレットを書き足しますが、本番運用時はこれらをスクリプトプロパティに格納して流出しないよう厳格に管理する必要があります。

  • 今回利用するGraph APIのエンドポイントはhttps://graph.microsoft.com/beta/usersとなります。
  • 要求する権限はscopeに半角スペースで区切って、Entra ID側で用意したものと同じものを設定します。
  • startoauthを実行して認証を実行すれば、スクリプトプロパティにAccess Tokenが格納されます。

HTML側コード

template.htmlとして記述しています。OAuth認証を行い結果を受け取って表示するだけに利用します。

  • 実際にこれらのコードで、startoauthを実行すると、スプレッドシート上で認証用のダイアログが出ます。
  • 認証でEntra IDアカウントにログインします(もしくは作成したonmicrosoft.comのアカウント)
  • 取得したAccess Tokenほかはスクリプトプロパティのoauth2.Graphという項目にガッツリ値が格納されます。ここにはAccess Token, Refresh Token, expire_inのタイムなどが入っています。
  • reset関数はログアウトされて、再度認証ができるようになります。

読み書きするコード

ユーザリスト読み出し

entraid.gsに記述しています。Entra ID側に登録されてるユーザの情報のうち、一部だけを取り出してスプレッドシートに一括書き出ししています。

  • OrgUnitPathはFAX番号を今回使ってるのでそこの値も取ってきています。

ユーザ情報一括反映

entraid.gsに記述しています。上記とは反対にスプシ側の記述情報を書きに行っていますが、今回はFAX番号のみ書き込みにしています。

  • 値がNullのセルの場合は、/CIFの値を書き込む用に指定しています。
  • リクエストはPATCHにて指定が必要です。
  • 無事に書き込みができるとレスポンスコードは204が返ってきます。
  • UrlfetchAppの連続実行制限をスルーするためにUtilities.sleepを0.3秒間入れています(単位:ms)。

図:無事に書き込めました。

注意事項

今回のコードではEntra IDのユーザはテスト用に用意した数件でしか検証していません。しかし、Entra ID側ユーザ数が膨大な場合、GASの連続実行時間6分の規制に掛かる可能性があります。

その場合、以下の6分の壁を超えるためのテクニックを利用して突破できるようにしてあげる必要があります(ウェイト処理は1件処理する毎0.3秒入れていますが、UrlfetchAppの429エラー対策の為ですので外すことは出来ません)。

UrlfetchApp.fetchAllにてまとめてリクエストを投げることが可能ですが、Graph API側は1度のリクエストで20件まで当時にバルク処理が出来るようです。

Google Apps Scriptで6分の壁(タイムアウト)を突破する【GAS】

Google Apps Scriptで6分の壁(タイムアウト)を突破する - 番外編【GAS】

関連リンク

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)