初心者のためのAzure AD B2Cカスタムポリシー概要

はじめに

  • Azure AD B2Cは、ユーザ情報の管理を行うと共に、アプリに代わってサインイン、パスワードリセット、プロフィール編集等のユーザ認証・編集機能を実行できます。ここでは、このようなユーザ認証・編集機能のカスタマイズが可能なカスタムポリシーの概要を説明します。
  • 読者として「カスタムポリシーの初心者」を想定しているため、「正確さ」よりも「分かりやすさ」を優先して説明しています。
  • SAML、OpenID Connect等のシングルサインオン関連の規格では、同じものを異なる用語で表現する場合があります。ここでは、可能な限りマイクロソフトのリファレンスで使用している用語を使用します。
  • カスタム ポリシーの公式リファレンスは次の通りです。

IDプロバイダとRelying Party

カスタムポリシーの開発の前提知識となるIDプロバイダ・Relying Partyについて説明します。
Azure AD B2Cのようにユーザアカウント・ユーザ情報の管理を行い、ユーザ認証・編集機能を提供する要素をIDプロバイダと呼びます。このユーザ認証・編集機能を使用する要素をRelying Partyと呼びます。Relying Partyは必要に応じて、IDプロバイダが提供ユーザ認証・編集機能をユーザに提供することができます。
(Relyingは「頼る」という意味で、ユーザ認証・管理をIDプロバイダに頼っているアプリやデバイス等を纏めて”Relying Party”と呼んでいるようです。)

  • ユーザ認証・編集機能は、サインイン・サインアップ、パスワードリセット、プロフィール編集等のタスク毎に決められた画面・処理を提供します。各タスクの画面・処理内容はRPポリシーと呼ばれるXMLファイルで定義されています。RPアプリで特定のタスクを実行する場合は、対応するRPポリシーを実行する必要があります。
    (マイクロソフトのリファレンスではRPポリシーのことを「証明書利用者ポリシー」と表記していますが、私にはピンと来ないので翻訳元の”Relying Party Policy”を使用しています。)
  • RPポリシーが実行されると、その定義内容に基づいてIDプロバイダがユーザとの対話を通じてユーザ認証やユーザ情報の編集を行います。処理に成功した場合はその旨を示すトークンをRPアプリに返却します。RPアプリではトークンの有無で処理の正常性を検証します。
  • RPアプリではユーザ情報を保持していません。IDプロバイダがトークンをRPアプリに返却する際、RPアプリで使用するユーザ情報も付与する必要があります。
  • 使用するユーザアカウントをAzure AD B2Cで管理することもできますが、TwitterやFacebook等の外部IDプロバイダで管理されるユーザアカウントを使用することもできます。Azure AD B2Cで管理されるユーザアカウントをローカルアカウント、外部IDプロバイダのユーザアカウントをソーシャルアカウントと呼んで区別します。
    (ローカルアカウントは実際にはAzure AD上で管理されており、ユーザ属性に対する操作はAzure ADに対して行われます。)
  • サインイン時の流れを説明します。
    1. アクセス要求: ユーザがRPアプリにアクセスを試行します。
    2. 承認要求: RPアプリでは、ユーザ認証を行うためにサインインRPポリシーを実行します。
    3. 入力要求: Azure AD B2Cは、RPポリシーの内容に基づいて、ユーザに認証画面を表示します。
    4. 資格情報の入力: ユーザは認証画面に資格情報を入力します。
    5. トークン発行: ユーザの認証が成功した場合、その旨を示すトークンと、メールアドレス、氏名等のユーザ情報を返却します。
    6. アクセス応答: RPアプリではトークンの検証が成功したら、当初のアクセス要求に対する応答を行います。

ユーザ体験と技術プロファイル

RPポリシーにおける処理フローをユーザ体験、処理フロー上の個々の処理を技術プロファイルとして定義します。
ここでは、例としてパスワード+ワンタイムパスワードでユーザを認証するユーザ体験を説明します。
(大枠が分かるよう細かい技術プロファイルは割愛しています。)

  • 構成要素は次の通りです。
    要素名説明
    RPポリシー
    (RelyingPolicy)
    使用するユーザ体験を指定します。ユーザ体験が正常終了した際、RPアプリに返却するトークンの仕様やトークンに含めるユーザ情報(ユーザID、メールアドレス、氏名等)を定義します。
    ユーザ体験
    (UserJourney)
    処理フローをオーケストレーションステップとして定義します。各ステップでは、実行条件や実行する技術プロファイルを指定します。
    技術プロファイル
    (TechnicalProfile)
    ユーザに対する認証画面の表示、入力されたパスワードの検証、Azure ADからユーザ情報(クレーム)の読み取り・書込み等の処理は、技術プロファイルとして定義します。
  • 上記のユーザ体験の流れを説明します。
    1. ステップ1:
      パスワード認証画面技術プロファイルを使って、ユーザに認証画面を表示します。パスワード認証画面技術プロファイルでは、入力されたユーザIDやパスワードをパスワード検証技術プロファイルで検証します。
    2. ステップ2:
      ユーザ属性読み取り技術プロファイルを使って、ユーザIDに対応するメールアドレスや氏名等のユーザ属性(クレーム)を取得します。
    3. ステップ3:
      OTP認証画面技術プロファイルを使って、ユーザにワンタイムパスワード認証画面を表示します。
      ユーザがコード送信ボタンをクリックした場合、OTPコード生成技術プロファイルでOTPコードを生成し、メール送信技術プロファイルでOTPコードをメールで送信します。
      ユーザがOTPコードを入力した場合、OTPコード検証技術プロファイルでそのコードを検証します。
      なお、メールアドレスが登録されていない場合、このステップをスキップします。
    4. ステップ4:
      RPアプリに返却するためのトークンを生成します。

技術プロファイルの詳細

技術プロファイルは、ユーザへの画面表示や入力内容の取得、Azure Active Directoryからのユーザ情報の取得などの様々な処理を定義できます。
ユーザ体験の実行中、技術プロファイルの入出力データはクレームとして一時保存され、他の技術プロファイルでも使用することができます。(ここでいう「クレーム」はプログラミング言語の変数のようなものです。)

  • 技術プロファイルで実行する処理はプロトコル・ハンドラ(Protocol/Handler)で指定します。
    • 指定できるプロトコル・ハンドラの種類は次の通りです。
    • 主にRPポリシー(RelyingParty要素内で定義する技術プロファイル)でOAuth1/2, OpenID Connect, SAMLプロトコルを使用します。その他のプロトコル・ハンドラをユーザ体験で使用します。経験的に使用頻度が高いのはセルフアサート、Azure AD、JWTトークン発行です。
    • なお、リファレンスでは「技術プロファイルの種類」として記載されていますが、ここでは「プロトコル・ハンドラの種類」と表記しています。
    No.プロトコル(物理名)ハンドラ説明
    1OAuth1(OAuth1)外部システムとの連携(フェデレーション)で使用
    主にRelyingParty用の技術プロファイルで使用。
    2OAuth2(OAuth2)
    3OpenID Connect
    (OpenIdConnect)
    4SAML(SAML2)
    5SAMLトークン発行
    (SAML2)
    SAMLアプリ用のトークンを発行する。
    (RPアプリがSAMLアプリの場合に使用)
    6Azure AD B2C専用
    (Proprietary)
    セルフアサート画面表示やユーザ入力の受付を行う。
    必要に応じて入力値等の検証を行うこともできる。
    7Azure ADローカルアカウントの属性の読み取り・書込みを行う。
    8Azure AD 多要素認証SMSを使ったコード送信・検証を行う。
    画面表示機能はなく、セルフアサートを使用する前提。
    (2021年12月現在、パブリックプレビュー)
    9電話要素電話番号の登録および検証を行う画面を提供する。
    10ワンタイムパスワードワンタイムパスワードの生成・検証を行う。
    画面表示の機能はない。
    11RESTfulプロバイダ外部のRESTfulサービスを実行する。
    12Application InsightsApplication Insightsにログを出力する。
    13要求変換クレーム変換(ClaimsTransformations)を実行する。
    14JWT トークン発行RPアプリに返却するトークンを生成する。
    通常、ユーザ体験の最後で実行される。
    15SSOセッションSSOセッションの管理方法を指定します。
    16IDトークンヒント
    (None)
    RPアプリから受信したJWTトークンから
    OAuth2認可要求を抽出する。
    招待メールからのサインアップのシナリオで使用。
  • プロトコル・ハンドラの基本的な動作は、メタデータ、入力クレーム、出力クレームで指定します。
  • 使用するプロトコル・ハンドラによって入力クレーム・出力クレームの意味や追加で必要な項目が異なります。
    詳細は、各プロトコル・ハンドラのリファレンスをご覧ください。

    • セルフアサートの例: 画面に表示する項目(クレーム)をOutputClaimsで定義します。各項目の初期値をInputClaimsで指定します。
    • Azure ADの例: メタデータに読み取りモードを指定した場合、検索対象となるユーザのオブジェクトIDやユーザプリンシパル名をInputClaimsに指定します。取得したいユーザ属性名をOutputClaimsに指定します。
    • RESTfulの例: メタデータにRESTサービスを利用するための認証方法やメソッド(GET/POST等)をメタデータに指定します。RESTに送信する要求パラメータ(クレーム)をInputClaimsに指定します。RESTサービスからの応答から取得するパラメータをOutputClaimsに指定します。認証に使用するキーは、暗号キー項目(CryptographicKeys)として指定します。
  • 技術プロファイルの処理前後でクレームを変換することができます。
    • 入力クレームの値が技術プロファイルで期待する値と異なる場合、入力クレーム変換を行って期待する値に変換することもできます。同様に、出力クレームの値が他の技術プロファイルの期待値と異なる場合、出力クレーム変換を行って期待する値に変換することができます。
    • 使用可能な変換はリファレンスをご覧ください。なお、変換の種類には、クレームの値を検証する変換も用意されており、後述の検証技術プロファイルで使用することもできます。
  • セルフアサートでは入力値を検証する技術プロファイルを指定できます。
    • ユーザの入力値の検証等を行うための技術プロファイル(検証技術プロファイル)を実行できます。
    • 前述のようなAzure Active Directoryから値を取得する技術プロファイルや、RESTful呼び出しを行う技術プロファイル等、一般的な技術プロファイルを検証技術プロファイルとして指定できます。
  • 冗長なユーザ認証処理はスキップできます。
    • プロフィール編集のユーザ体験では、ユーザ認証用の画面表示・処理後にプロフィール編集画面を表示するフローになります。既に認証済みのユーザの場合、ユーザ認証用の画面表示・処理は不要なので、これらをスキップしてプロフィール編集画面を表示する必要があります。これは当該技術プロファイルで、「セッション管理用技術プロファイルの使用」(UseTechnicalProfileForSessionManagement)を指定することで実現できます。
    • 分かりやすいようスキップと記載していますが、実際には技術プロファイル実行時にセッションから状態が復元されて自動的処理されます。

カスタムポリシーの作成方法

  • 実行環境や開発環境の準備は、マイクロソフトのリファレンスをご覧ください。
  • カスタムポリシーはXMLファイルなので、メモ帳などのテキストエディタがあれば編集できます。
    作成したカスタムポリシー(XMLファイル)は、Azureポータルからデプロイ(利用可能な状態)や動作確認できます。(アプリがなくても、カスタムポリシーを単独で実行可能です。)
  • ゼロからカスタムポリシーを作成するのは大変なので、いくつかのシナリオ向けのひな形やサンプルのXMLがスターターパックとして公開されています。この中から業務要件に近いもの選択して開発する流れになります。
  • 各シナリオには次のようなファイルが用意されています。
    ユーザ体験や技術プロファイルは継承の仕組みを使って定義できます。ベースファイルには各シナリオで使用する基本的な定義があるので、その定義で足りない場合は拡張ファイルやRPファイルで定義を追加したり、同じ項目を別の値で上書きして定義します。
  • 次のサイトから豊富なサンプルを確認できます。
    2021年12月現在で80個程のサンプルがあります。
    業務要件に近いサンプルが見つけ、正常に動作するのを確認しつつ、少しづつ業務要件に近づけて改修していくことをお薦めします。いきなり大きく改修して動作しないと、問題の切り分けがとても大変なため。
    GitHub

    Azure AD B2C custom policy solutions and samples. Contribute…

  • 開発やデバッグの効率化のため、次の記事にあるように、Visual Studio Codeとプラグインの導入や、Azure Insightsの有効化をお薦めします。
    (プラグインをインストール後、Visual Studio CodeでXMLファイルがあるフォルダを開くとプラグインが実行されます。)

    カスタム ポリシーの実行を追跡するための Application Insights の設定方法。…

実装時の参考

  • プレビュー機能の正式リリース予定が分からない。
    • 使いたい機能がプレビュー機能だったりすることがあります。一般的な現場では、「プレビュー版」「ベータ版」等のような予定が不透明なものの使用は、承認されません。正式なリリース予定を伝えられれば承認してもらえるかもしれないのですが、2021年11月現在でリリース予定は公開されていません。マイクロソフトとしては、顧客からのフィードバックに基づいて随時更新しているようで、予定の明言が難しいようです。
    • 結果として、いつのまにかプレビュー機能が公式機能としてリリースされていたりしますが、そのようなアナウンスがありません。
      以前はDisplayControlはプレビュー機能だったのですが、いつのまにか公式機能になっていたります。また、以前は存在しなかったTrustFrameworkLocalization.xmlが追加されていたります。
    • こんな感じで、現場でのプレビュー機能の使用の承認、変更の追跡が大変です。
      プレビュー機能であっても、マイクロソフトのリファレンスに記載があるものは、ある程度サポートしてくれるようです。
  • 「できそう」で「できない」場合がある。
    • パスワードの有効期限の設定ができません。サンプルを参考に独自に実装する必要があります。
    • パスワードの複雑性の検証もカスタムポリシーで独自に実装する必要があります。パスワードの使いまわしの検証(変更パスワード履歴の保持)は、カスタムポリシーの定義だけでは実現できないので、そのような検証を行うRESTサービスを用意する必要があります。
    • 「管理者によるパスワードリセット後、ユーザの初回サインイン後に新しいパスワード設定を強制する」ができません。サンプルを参考に独自に実装する必要があります。
  • デバッグが非常に難しい。
    • カスタムポリシー上の技術プロファイル等は複数のファイルで継承して定義することができます。差分で定義できるので便利なのですが、当該技術プロファイルが最終的にどのような定義になっているかを直接確認できず、各ファイルを開いて定義内容を把握する必要があります。
    • カスタムポリシー実行時にエラーがあると「エラーが発生しました。」「不正な要求です。」等のようなエラーメッセージやログが出力されるだけで、原因個所の特定が難しい場合が多々あります。
    • このような状況では、地道に定義を修正・追加して、どこまで正常に動作するか?何を追加したらエラーになるか?で原因個所を特定していく必要があります。ある程度のSEやプログラマであれば、このような問題切り分けは可能だと思いますが、初心者には想像が難しく、厳しい作業になると思います。
    • Azureポータルから、Azure Insightsに出力されるログを確認できますが、出力内容が大量でデバッグには不向きです。前述のようなVisual Studio Codeのプラグインを使うと、Azure Insightsのログに含まれるクレームやエラーメッセージを整形して表示できるので、デバッグにとても役立ちます。
    • まず、サンプル等の正常に動作するカスタムポリシーを用意した上で、少しづつ改修・動作確認して、完成させていくような進め方をお薦めします。上記のように原因の詳細をピンポイントで教えてくれるわけではなく、2重3重の間違いがあると問題の切り分けがとても難しくなるためです。