Microsoft ID プラットフォームは、Microsoft Entra アプリケーション ギャラリーとカスタム アプリケーションのほとんどの事前統合アプリケーションで シングル サインオン (SSO) をサポートしています。 ユーザーが、Microsoft ID プラットフォーム経由で OIDC プロトコルを使いアプリケーションに対する認証を行うと、トークンがアプリケーションに送信されます。 アプリケーションはトークンを検証し、ユーザー名とパスワードの入力を求める代わりに、そのトークンを使ってユーザーをサインインさせます。
OIDC および OAuth アプリケーションで使用されるこれらの JSON Web トークン (JWT) には、 クレームと呼ばれるユーザーに関する情報が含まれています。 要求とは、そのユーザーに発行するトークンの中にあるユーザーに関する ID プロバイダーが提示した情報を指します。 OIDC 応答では、要求データは通常、JWT の形式で ID プロバイダーによって発行された ID トークンに含まれます。
クレームを表示または編集する
オプションの JWT 要求は、元のアプリケーションの登録で構成できますが、エンタープライズ アプリケーション内でも構成できます。 アプリケーションに対して JWT で発行されたクレームを表示または編集するには:
- Microsoft Entra 管理センターに、少なくともクラウド アプリケーション管理者としてサインインします。
- Entra ID>Enterprise アプリ>すべてのアプリケーションに移動します。
- アプリケーションを選択し、左側のメニューで [シングル サインオン] を選択し、[属性と要求] セクションで [編集] を選択します。
アプリケーションでは、さまざまな理由でクレームのカスタマイズが必要になる場合があります。 たとえば、アプリケーションで、別の一連のクレーム URI やクレーム値が必要な場合です。 [属性と要求] セクションを使用すると、アプリケーションの要求を追加または削除できます。 ユース ケースに基づいて、アプリケーションに固有のカスタム クレームを作成することもできます。
次の手順では、定数値を割り当てる方法について説明します。
- 変更するクレームを選択します。
- 組織に従って Source 属性 に引用符なしで定数値を入力し、[保存] を選択 します。
属性の概要には、定数値が表示されます。
特別なクレームの変換
特別なクレームの変換関数を使用できます。
機能 | 説明 |
---|---|
ExtractMailPrefix() | メール アドレスまたはユーザー プリンシパル名からドメイン サフィックスを除去します。 この関数は、ユーザー名の最初の部分のみを抽出します。 たとえば、joe_smith の代わりに joe_smith@contoso.com となります。 |
ToLower() | 選択した属性の文字を小文字に変換します。 |
トアッパー() | 選択した属性の文字を大文字に変換します。 |
アプリケーション固有のクレームを追加する
アプリケーション固有の要求を追加するには:
- [ユーザー属性] & [要求] で、[新しい要求の追加] を選択して、[ユーザー要求の管理] ページを開きます。
- 要求の 名前 を入力します。 値は、URI パターンに厳密に従う必要はありません。 URI パターンが必要な場合は、[ 名前空間] フィールドに配置できます。
- 要求の値を取得する ソース を選択します。 ソース属性のドロップダウンからユーザー属性を選択するか、または要求として生成する前にユーザー属性に変換を適用することができます。
要求の変換
ユーザー属性に変換を適用するには、次の手順を行います。
- [ 要求の管理] で、要求ソースとして [変換 ] を選択し、[ 変換の管理 ] ページを開きます。
- 変換ドロップダウンから関数を選択します。 選択した関数に応じて、変換で評価するパラメーターと定数値を指定します。
-
ソースを複数値として扱う は、変換がすべての値に適用されるか、最初の値のみに適用されるかを示します。 既定では、複数値クレームの最初の要素に変換が適用されます。 このチェックボックスをオンにすると、すべてに適用されます。 このチェックボックスは、複数値の属性に対してのみ有効になります。 たとえば、「
user.proxyaddresses
」のように入力します。 - 複数の変換を適用するには、[ 変換の追加] を選択します。 要求には、最大 2 つの変換を適用できます。 たとえば、最初に
user.mail
のメール プレフィックスを抽出できます。 次に、文字列を大文字にします。
次の関数を使用して、要求を変換できます。
機能 | 説明 |
---|---|
ExtractMailPrefix() | メール アドレスまたはユーザー プリンシパル名からドメイン サフィックスを除去します。 この関数は、ユーザー名の最初の部分のみを抽出します。 たとえば、joe_smith の代わりに joe_smith@contoso.com となります。 |
ジョイン() | 2 つの属性を結合することで、新しい値を作成します。 必要に応じて、2 つの属性の間に区切り記号を使用できます。 NameID の要求の変換で、変換入力にドメイン部分がある場合、Join() 関数は特定の動作をします。 入力からドメイン部分を削除した後、区切り記号および選択されたパラメーターを結合します。 たとえば、変換の入力が joe_smith@contoso.com 、区切り記号が @ 、パラメーターが fabrikam.com の場合、この入力の組み合わせでは joe_smith@fabrikam.com という結果になります。 |
小文字に変換 | 選択した属性の文字を小文字に変換します。 |
ToUppercase() | 選択した属性の文字を大文字に変換します。 |
contains() | 入力が指定した値と一致する場合、属性または定数を出力します。 一致しない場合は、別の出力を指定できます。 たとえば、値がユーザーのメール アドレスで、そこに @contoso.com というドメインが含まれる場合、そのクレームは出力し、それ以外の場合はユーザーのプリンシパル名を出力したいとします。 この関数を実行するには、次の値を構成します。パラメーター 1 (入力): user.email 値: "@contoso.com" Parameter 2 (出力): user.email Parameter 3 (一致しない場合の出力): user.userprincipalname |
EndWith() | 入力が指定した値で終わっている場合、属性または定数を出力します。 一致しない場合は、別の出力を指定できます。 たとえば、ユーザーの従業員 ID が 000 で終わっている場合は従業員 ID を値とする要求を出力し、それ以外の場合は拡張属性を出力したいものとします。 この関数を実行するには、次の値を構成します。パラメーター 1 (入力):user.employeeid 値: "000" Parameter 2 (出力): user.employeeid Parameter 3 (一致しない場合の出力): user.extensionattribute1 |
StartWith() ()を使用します。 | 入力が指定した値で始まっている場合、属性または定数を出力します。 一致しない場合は、別の出力を指定できます。 たとえば、国またはリージョンが US で始まっている場合はユーザーの従業員 ID を値とする要求を出力し、それ以外の場合は拡張属性を出力したいものとします。 この関数を実行するには、次の値を構成します。パラメーター 1 (入力): user.country 値: "US" Parameter 2 (出力): user.employeeid Parameter 3 (一致しない場合の出力): user.extensionattribute1 |
Extract() - 照合後 | 指定した値との一致より後の部分文字列を返します。 たとえば、入力の値が Finance_BSimon で、一致する値が Finance_ の場合、クレームの出力は BSimon です。 |
Extract() - マッチングの前 | 指定した値との一致より前の部分文字列を返します。 たとえば、入力の値が BSimon_US で、一致する値が _US の場合、クレームの出力は BSimon です。 |
Extract() - 照合の間 | 指定した値との一致より前の部分文字列を返します。 たとえば、入力の値が Finance_BSimon_US 、1 番目の一致する値が Finance_ 、2 番目の一致する値が _US の場合、クレームの出力は BSimon です。 |
ExtractAlpha() - プレフィックス | 文字列のプレフィックスのアルファベット部分を返します。 たとえば、入力の値が BSimon_123 の場合、BSimon が返されます。 |
ExtractAlpha() - サフィックス | 文字列のサフィックスのアルファベット部分を返します。 たとえば、入力の値が 123_Simon の場合、Simon が返されます。 |
ExtractNumeric() - プレフィックス | 文字列のプレフィックスの数字部分を返します。 たとえば、入力の値が 123_BSimon の場合、123 が返されます。 |
ExtractNumeric() - サフィックス | 文字列のサフィックスの数字部分を返します。 たとえば、入力の値が BSimon_123 の場合、123 が返されます。 |
IfEmpty() | 入力が null または空の場合、属性または定数を出力します。 たとえば、特定のユーザーの従業員 ID が空の場合に、拡張属性に格納されている属性を出力したいとします。 この関数を実行するには、次の値を構成します。 Parameter 1 (入力): user.employeeid Parameter 2 (出力): user.extensionattribute1 Parameter 3 (一致しない場合の出力): user.employeeid |
IfNotEmpty() | 入力が null または空ではない場合、属性または定数を出力します。 たとえば、特定のユーザーの従業員 ID が空でない場合に、拡張属性に格納されている属性を出力したいとします。 この関数を実行するには、次の値を構成します。 Parameter 1 (入力): user.employeeid Parameter 2 (出力): user.extensionattribute1 |
Substring() - 固定長 | 指定した位置にある文字から始まる文字列要求の種類の一部が抽出され、指定した文字数が返されます。 SourceClaim - 実行する必要がある変換のクレーム ソース。 StartIndex - このインスタンス内の substring の 0 から始まる開始文字位置。 Length - substring の文字の長さ。 次に例を示します。 sourceClaim - これを今すぐ抽出してください スタートインデックス - 6 長さ - 11 出力: ExtractThis |
Substring() - エンドオブストリング | 指定した位置にある文字から始まる文字列要求の種類の一部が抽出され、指定した開始インデックスから要求の残りが返されます。 SourceClaim - 変換のクレーム ソース。 StartIndex - このインスタンス内の substring の 0 から始まる開始文字位置。 次に例を示します。 sourceClaim - これを今すぐ抽出してください スタートインデックス - 6 出力: ExtractThisNow |
正規表現Replace() | RegexReplace() 変換は、入力パラメーターとして次を受け入れます。 - パラメーター1:正規表現入力としてのユーザー属性 - ソースを複数値として信頼するオプション ‐正規表現パターン ‐置換パターン。 置換パターンには、正規表現出力グループを指す参照、および追加の入力パラメーターと共に、静的テキスト形式を含めることができます。 |
他の変換が必要な場合は、SaaS アプリケーション カテゴリの Microsoft Entra ID のフィードバック フォーラムでアイデアを送信してください。
正規表現ベースのクレーム変換
次の画像は、変換の第 1 レベルの例を示したものです。
次の表では、変換の第 1 レベルに関する情報を示します。 表に示されているアクションは、前の画像のラベルに対応しています。 [ 編集] を 選択して要求変換ブレードを開きます。
アクション | フィールド | 説明 |
---|---|---|
1 | Transformation |
[変換] オプションから RegexReplace() オプションを選択して、要求変換に正規表現ベースの要求変換メソッドを使用します。 |
2 | Parameter 1 |
正規表現変換の入力。 たとえば、admin@fabrikam.com のようなユーザー メール アドレスを含む user.mail。 |
3 | Treat source as multivalued |
一部の入力ユーザー属性は、複数値のユーザー属性になれます。 選択したユーザー属性が複数の値をサポートしていて、変換に複数の値を使用する場合は、[ ソースを複数値として扱う] を選択する必要があります。 オンにした場合は、すべての値が正規表現の照合に使われ、オフにした場合は、最初の値のみが使われます。 |
4 | Regex pattern |
"パラメーター 1" として選ばれたユーザー属性の値に対して評価される正規表現。 たとえば、ユーザーのメール アドレスからユーザーの別名を抽出する正規表現は、(?'___domain'^.*?)(?i)(\@fabrikam\.com)$ と表します。 |
5 | Add additional parameter |
複数のユーザー属性を変換に使用できます。 その場合、属性の値は正規表現の変換出力とマージされます。 最大 5 つの追加パラメーターがサポートされています。 |
6 | Replacement pattern |
置換パターンは、正規表現の結果に対するプレースホルダーを含むテキスト テンプレートです。 {group-name} のように、すべてのグループ名を中かっこで囲む必要があります。 たとえば、管理者は他のドメイン名 (例: xyz.com ) と共にユーザーの別名を使い、国名をそれとマージしたいとします。 このケースでは、置換パターンは {country}.{___domain}@xyz.com になります。{country} は入力パラメーターの値であり、{___domain} は正規表現の評価からのグループ出力です。 このようなケースでは、予想される結果は US.swmal@xyz.com になります。 |
次の画像は、変換の 2 番目のレベルの例を示したものです。
次の表では、変換の 2 番目のレベルに関する情報を示します。 表に示されているアクションは、前の画像のラベルに対応しています。
アクション | フィールド | 説明 |
---|---|---|
1 | Transformation |
正規表現ベースのクレーム変換は、第 1 の変換に限定されず、第 2 レベルの変換としても使用できます。 その他のいかなる変換方法も、最初の変換として使用できます。 |
2 | Parameter 1 |
RegexReplace() が第 2 レベル変換として選択されている場合、第 1 レベル変換の出力が第 2 レベル変換の入力として使用されます。 変換を適用するには、第 2 レベルの正規表現式が、第 1 の変換の出力と一致する必要があります。 |
3 | Regex pattern |
正規表現パターン は、第 2 レベル変換の正規表現です。 |
4 | Parameter input |
第 2 レベルの変換に対するユーザー属性の入力。 |
5 | Parameter input |
パラメーターが不要になった場合、管理者は選んだ入力パラメーターを削除できます。 |
6 | Replacement pattern |
置換パターンは、正規表現の結果グループ名、入力パラメーター グループ名、静的テキスト値のプレースホルダーを含むテキスト テンプレートです。
{group-name} のように、すべてのグループ名を中かっこで囲む必要があります。 たとえば、管理者は他のドメイン名 (例: xyz.com ) と共にユーザーの別名を使い、国名をそれとマージしたいとします。 このケースでは、置換パターンは {country}.{___domain}@xyz.com になります。{country} は入力パラメーターの値であり、{___domain} は正規表現の評価からのグループ出力です。 このようなケースでは、予想される結果は US.swmal@xyz.com になります。 |
7 | Test transformation |
RegexReplace() 変換は、 パラメーター 1 に対して選択されたユーザー属性の値が 、Regex パターン テキスト ボックスに指定された正規表現と一致する場合にのみ評価されます。 一致しない場合は、既定のクレーム値がトークンに追加されます。 入力パラメーター値に対して正規表現を検証するには、変換ブレード内でテスト エクスペリエンスを使用できます。 このテスト エクスペリエンスはダミー値でのみ動作します。 追加の入力パラメーターを使うと、実際の値ではなく、パラメーターの名前がテスト結果に追加されます。 テスト セクションにアクセスするには、[ テスト変換] を選択します。 |
次の図は、変換のテストの例を示したものです。
次の表では、変換のテストに関する情報を示します。 表に示されているアクションは、前の画像のラベルに対応しています。
アクション | フィールド | 説明 |
---|---|---|
1 | Test transformation |
[閉じる] または [(X)] ボタンを選択してテスト セクションを非表示にし、ブレードで [ テスト変換 ] ボタンをもう一度レンダリングします。 |
2 | Test regex input |
正規表現テストの評価に使われる入力を受け入れます。 正規表現ベースのクレーム変換が第 2 レベルの変換として構成されている場合、第 1 の変換の予想される出力を値として指定します。 |
3 | Run test |
テスト正規表現入力が指定され、 Regex パターン、 置換パターン 、 および入力パラメーター が構成されたら、[ テストの実行] を選択して式を評価できます。 |
4 | Test transformation result |
評価に成功すると、テスト変換の出力が テスト変換の結果 ラベルに対してレンダリングされます。 |
5 | Remove transformation |
2 番目のレベルの変換は、[変換の 削除] を選択して削除できます。 |
6 | Specify output if no match |
正規表現と一致しないパラメーター 1 に対して正規表現入力値が構成されている場合、変換はスキップされます。 このような場合は、代替ユーザー属性を構成できます。これは、 一致しない場合に出力を指定するチェック をオンにして、要求のトークンに追加されます。 |
7 | Parameter 3 |
条件に一致しない場合に代替ユーザー属性を返す必要があり、一致しない場合の出力を指定が選択されている場合は、ドロップダウンメニューを使用して代替ユーザー属性を選択できます。 このドロップダウンは 、パラメーター 3 (一致しない場合の出力) に対して使用できます。 |
8 | Summary |
ブレードの下部には、簡単なテキストで変換の意味を説明するフォーマットの概要が表示されます。 |
9 | Add |
変換の構成設定が検証されたら、[ 追加] を選択して要求ポリシーに保存できます。 [要求の管理] ブレードで [保存] を選択して変更を保存します。 |
RegexReplace() 変換は、グループ要求変換でも使用できます。
変換の検証
[テストの追加] または [実行] を選択した後に次の条件が発生した場合に、メッセージに詳細が表示されます。
- ユーザー属性が重複する入力パラメーターが使用された。
- 使われていない入力パラメーターが見つかりました。 定義された入力パラメーターは、置換パターン テキストでそれぞれ使用される必要があります。
- 指定されたテスト正規表現入力が、指定された正規表現と一致しません。
- 置換パターンのグループのソースが見つからない。
条件に基づいてクレームを出力する
ユーザーの種類とユーザーが属するグループに基づいて、要求のソースを指定することができます。
ユーザーの種類は次のとおりです。
- Any - すべてのユーザーがアプリケーションにアクセスできます。
- メンバー: テナントのネイティブ メンバー
- すべてのゲスト: ユーザーは、Microsoft Entra ID の有無にかかわらず外部組織から移動しました。
- Microsoft Entra ゲスト: ゲスト ユーザーは、Microsoft Entra ID を使用して別の組織に属しています。
- 外部ゲスト: ゲスト ユーザーは、Microsoft Entra ID を持たない外部組織に属しています。
ユーザーの種類が役立つのは、クレームのソースが、ゲストとアプリケーションにアクセスする従業員とで異なる場合です。 ユーザーが従業員である場合は NameID を user.email から取得するように指定できます。 ユーザーがゲストの場合は、NameID は user.extensionattribute1 から取得されます。
要求条件を追加するには、次の手順を行います。
- [ 要求の管理] で、[要求の条件] を展開します。
- ユーザーの種類を選択します。
- ユーザーが属するグループを選択します。 特定のアプリケーションに対するすべての要求で、最大 50 個の一意のグループを選択できます。
- 要求の値を取得する ソース を選択します。 ソース属性のドロップダウンからユーザー属性を選択するか、または要求として生成する前にユーザー属性に変換を適用することができます。
条件を追加する順序は重要です。 Microsoft Entra はまず、すべての条件をソース Attribute
で評価し、クレームでどの値を出力するかを決定するためにすべての条件をソース Transformation
で評価します。 Microsoft Entra ID は、同じソースで上から下まで条件を評価します。 クレームによって、クレームの式と一致する最後の値が出力されます。
IsNotEmpty
や Contains
などの変換は、制限のように機能します。
たとえば、Britta Simon は Contoso テナントのゲスト ユーザーです。 Britta は、同様に Microsoft Entra ID を使用する別の組織に属しています。 Fabrikam アプリケーションが次のように構成されている場合、Britta が Fabrikam にサインインしようとすると、Microsoft ID プラットフォームで条件が評価されます。
まず、Microsoft ID プラットフォームは、Britta のユーザーの種類が [すべてのゲスト] であるかどうかを確認します。 種類は [すべてのゲスト] であるため、Microsoft ID プラットフォームは要求のソースを user.extensionattribute1
に割り当てます。 次に、Microsoft ID プラットフォームは、Britta のユーザーの種類が Microsoft Entra ゲストであるかどうかを確認します。 種類は [すべてのゲスト] であるため、Microsoft ID プラットフォームは要求のソースを user.mail
に割り当てます。 最終的に、クレームは Britta の user.mail
の値を使って出力されます。
もう 1 つの例として、Britta Simon が次の構成を使用してサインインしようとする場合を考えてみます。 Microsoft Entra はまず、すべての条件をソース Attribute
で評価します。 Britta のユーザータイプが user.mail
である場合、要求の根拠は です。 次に、変換が Microsoft Entra ID によって評価されます。 Britta はゲストであるため、user.extensionattribute1
がクレームの新しいソースです。 Britta は Microsoft Entra ゲストにあるため、 user.othermail
がこの要求の新しいソースです。 最終的に、クレームは Britta の user.othermail
の値を使って出力されます。
最後の例として、Britta の user.othermail
が構成されていない場合、または空の場合にどうなるかを考えます。 どちらの場合も、条件エントリは無視され、クレームは user.extensionattribute1
にフォールバックします。
セキュリティに関する考慮事項
トークンを受信するアプリケーションは、改ざんできないクレーム値に依存します。 クレームのカスタマイズによってトークンの内容を変更すると、この前提は通用しなくなる可能性があります。 アプリケーションは、悪意のあるアクターによって作成されたカスタマイズからアプリケーションを保護するためにトークンが変更されたことを明示的に確認する必要があります。 次のいずれかの方法で不適切なカスタマイズから保護します。
これを指定しないと、Microsoft Entra ID は AADSTS50146エラー コードを返します。
カスタム署名キーを構成する
マルチテナントのアプリでは、通常、カスタム署名キーが使用されます。 アプリ マニフェストには acceptMappedClaims
を設定しないでください。 Azure portal でアプリをセットアップすると、アプリ登録オブジェクトとサービス プリンシパルがテナントに作成されます。 そのアプリでは Azure グローバル サインイン キーを使用します。このキーではトークンのクレームをカスタマイズできません。 トークンにカスタム クレームを使用するには、証明書からカスタム サインイン キーを作成してサービス プリンシパルに追加します。 テスト目的で、自己署名証明書を使用してもかまいません。 カスタム署名キーを設定した後、アプリケーションのコードでトークン署名キーを検証する必要があります。
次の情報をサービス プリンシパルに追加します。
証明書からエクスポートした PFX ファイルから、base-64 でエンコードした秘密キーと公開キーを抽出します。 “Sign” に使用する keyId
の keyCredential
が keyId
の passwordCredential
に一致することを確認します。 証明書の拇印のハッシュを取得することで、customkeyIdentifier
を生成できます。
リクエスト
注
最初に、Microsoft Entra 管理センターのアプリ登録ブレードから新しく作成されたアプリの サービス プリンシパル ロック構成 を無効にしてから、サービス プリンシパルに対して PATCH を実行すると、400 無効な要求が発生します。
次の例は、カスタム署名キーをサービス プリンシパルに追加する HTTP PATCH 要求の形式を示しています。
keyCredentials
プロパティの “key” の値は、読みやすいように短縮してあります。 この値は base-64 でエンコードしてあります。 秘密キーでは、プロパティの “usage” (用途) は Sign
です。 公開キーでは、プロパティの “usage” (用途) は Verify
です。
PATCH https://graph.microsoft.com/v1.0/servicePrincipals/aaaaaaaa-bbbb-cccc-1111-222222222222
Content-type: servicePrincipals/json
Authorization: Bearer {token}
{
"keyCredentials":[
{
"customKeyIdentifier": "aB1cD2eF3gH4iJ5kL6-mN7oP8qR=",
"endDateTime": "2021-04-22T22:10:13Z",
"keyId": "aaaaaaaa-0b0b-1c1c-2d2d-333333333333",
"startDateTime": "2020-04-22T21:50:13Z",
"type": "X509CertAndPassword",
"usage": "Sign",
"key":"cD2eF3gH4iJ5kL6mN7-oP8qR9sT==",
"displayName": "CN=contoso"
},
{
"customKeyIdentifier": "aB1cD2eF3gH4iJ5kL6-mN7oP8qR=",
"endDateTime": "2021-04-22T22:10:13Z",
"keyId": "bbbbbbbb-1c1c-2d2d-3e3e-444444444444",
"startDateTime": "2020-04-22T21:50:13Z",
"type": "AsymmetricX509Cert",
"usage": "Verify",
"key": "cD2eF3gH4iJ5kL6mN7-oP8qR9sT==",
"displayName": "CN=contoso"
}
],
"passwordCredentials": [
{
"customKeyIdentifier": "aB1cD2eF3gH4iJ5kL6-mN7oP8qR=",
"keyId": "cccccccc-2d2d-3e3e-4f4f-555555555555",
"endDateTime": "2022-01-27T19:40:33Z",
"startDateTime": "2020-04-20T19:40:33Z",
"secretText": "mypassword"
}
]
}
PowerShell でカスタム署名キーを設定する
PowerShell を使用して MSAL パブリック クライアント アプリケーションをインスタンス化 し、 承認コード付与 フローを使用して Microsoft Graph の委任されたアクセス許可アクセス トークンを取得します。 このアクセス トークンを使用して Microsoft Graph を呼び出し、サービス プリンシパルに対してカスタム署名キーを設定します。 カスタム署名キーを構成したら、アプリケーション コードで トークン署名キーを検証する必要があります。
このスクリプトを実行するには、次のものが必要です。
- Azure portal のエンタープライズ アプリケーションのアプリケーションのエントリの [概要 ] ブレードにある、アプリケーションのサービス プリンシパルのオブジェクト ID。
- ユーザーをサインインさせ、Microsoft Graph を呼び出すアクセス トークンを取得するためのアプリの登録。 Azure portal の [App registrations]\(アプリの登録)\ の目的のアプリケーションの項目の [Overview]\(概要\) ブレードで、このアプリのアプリケーション (クライアント) ID を取得します。 アプリを登録するには、次のものを設定する必要があります。
- "http://localhost" のリダイレクト URI。モバイル アプリケーションとデスクトップアプリケーション プラットフォームの構成に記載されています。
- API のアクセス許可で、Microsoft Graph によって委任されたアクセス許可 Application.ReadWrite.All と User.Read (これらのアクセス許可に対する管理者の同意を必ず付与してください)。
- ログインして Microsoft Graph アクセス トークンを取得するユーザー。 このユーザーは、次の Microsoft Entra 管理者ロールのどれかを持っている必要があります (サービス プリンシパルの更新に必要です)。
- クラウド アプリケーション管理者
- アプリケーション管理者
- アプリケーションのカスタム署名キーに設定する証明書。 自己署名証明書を作成する方法と、信頼できる証明機関から証明書を取得する方法があります。 スクリプトでは、証明書に含まれる次のものを使用します。
- 公開キー (通常は .cer ファイル)
- PKCS#12 形式の秘密キー ( .pfx ファイル内)
- 秘密キーのパスワード (.pfx ファイル)
重要
Microsoft Entra ID では他の形式をサポートしていないため、秘密キーは PKCS#12 形式である必要があります。 誤った形式を使った場合、証明書情報を保持する keyCredentials
の存在するサービス プリンシパルを Microsoft Graph で PATCH すると、"Invalid certificate: Key value is invalid certificate" (無効な証明書: キー値が無効な証明書です) というエラーが発生する場合があります。
##########################################################
# Replace the variables below with the appropriate values
$fqdn="yourDomainHere" # This is used for the 'issued to' and 'issued by' field of the certificate
$pwd="password" # password for exporting the certificate private key
$tenantId = "aaaabbbb-0000-cccc-1111-dddd2222eeee" # Replace with your Tenant ID
$appObjId = "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb" # Replace with the Object ID of the App Registration
##########################################################
# Create a self-signed cert
$cert = New-SelfSignedCertificate -certstorelocation cert:\currentuser\my -DnsName $fqdn
$pwdSecure = ConvertTo-SecureString -String $pwd -Force -AsPlainText
$path = 'cert:\currentuser\my\' + $cert.Thumbprint
$___location="C:\\temp" # path to folder where both the pfx and cer file will be written to
$cerFile = $___location + "\\" + $fqdn + ".cer"
$pfxFile = $___location + "\\" + $fqdn + ".pfx"
# Export the public and private keys
Export-PfxCertificate -cert $path -FilePath $pfxFile -Password $pwdSecure
Export-Certificate -cert $path -FilePath $cerFile
$pfxpath = $pfxFile # path to pfx file
$cerpath = $cerFile # path to cer file
$password = $pwd # password for the pfx file
# Check PowerShell version (minimum 5.1) (.Net) or PowerShell Core (.Net Core) and read the certificate file accordingly
if ($PSVersionTable.PSVersion.Major -gt 5)
{
$core = $true
}
else
{
$core = $false
}
# this is for PowerShell Core
$Secure_String_Pwd = ConvertTo-SecureString $password -AsPlainText -Force
# reading certificate files and creating Certificate Object
if ($core)
{
$pfx_cert = get-content $pfxpath -AsByteStream -Raw
$cer_cert = get-content $cerpath -AsByteStream -Raw
$cert = Get-PfxCertificate -FilePath $pfxpath -Password $Secure_String_Pwd
}
else
{
$pfx_cert = get-content $pfxpath -Encoding Byte
$cer_cert = get-content $cerpath -Encoding Byte
# calling Get-PfxCertificate in PowerShell 5.1 prompts for password - using alternative method
$cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($pfxpath, $password)
}
# base 64 encode the private key and public key
$base64pfx = [System.Convert]::ToBase64String($pfx_cert)
$base64cer = [System.Convert]::ToBase64String($cer_cert)
# getting id for the keyCredential object
[string]$guid1 = New-Guid
[string]$guid2 = New-Guid
# get the custom key identifier from the certificate thumbprint:
$hasher = [System.Security.Cryptography.HashAlgorithm]::Create('sha256')
$hash = $hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($cert.Thumbprint))
$customKeyIdentifier = [System.Convert]::ToBase64String($hash)
# get end date and start date for our keycredentials
$endDateTime = ($cert.NotAfter).ToUniversalTime().ToString( "yyyy-MM-ddTHH:mm:ssZ" )
$startDateTime = ($cert.NotBefore).ToUniversalTime().ToString( "yyyy-MM-ddTHH:mm:ssZ" )
# building our json payload
$object = [ordered]@{
keyCredentials = @(
[ordered]@{
customKeyIdentifier = $customKeyIdentifier
endDateTime = $endDateTime
keyId = $guid1
startDateTime = $startDateTime
type = "AsymmetricX509Cert"
usage = "Sign"
key = $base64pfx
displayName = "CN=$fqdn"
},
[ordered]@{
customKeyIdentifier = $customKeyIdentifier
endDateTime = $endDateTime
keyId = $guid2
startDateTime = $startDateTime
type = "AsymmetricX509Cert"
usage = "Verify"
key = $base64cer
displayName = "CN=$fqdn"
}
)
passwordCredentials = @(
[ordered]@{
customKeyIdentifier = $customKeyIdentifier
displayName = "CN=$fqdn"
keyId = $guid1
endDateTime = $endDateTime
startDateTime = $startDateTime
secretText = $password
hint = $null
}
)
}
Connect-MgGraph -tenantId $tenantId -Scopes Application.ReadWrite.All
$graphuri = "https://graph.microsoft.com/v1.0/applications/$appObjId"
Invoke-MgGraphRequest -Method PATCH -Uri $graphuri -Body $object
$json = $object | ConvertTo-Json -Depth 99
Write-Host "JSON Payload:"
Write-Output $json
トークン署名キーを承認する
要求マッピングが有効になっているアプリでは、appid={client_id}
にを追加してトークン署名キーを検証する必要があります。 次の例は、使う必要がある OpenID Connect メタデータ ドキュメントの形式を示しています。
https://login.microsoftonline.com/{tenant}/v2.0/.well-known/openid-configuration?appid={client-id}
アプリケーション マニフェストを更新する
シングル テナント アプリの場合は、acceptMappedClaims
プロパティをtrue
でするように設定できます。
apiApplication
リソースの種類に関するドキュメントに記載されているとおり。 プロパティを設定することで、カスタム署名キーを指定せずに、アプリケーションでクレーム マッピングが使用できます。
警告
マルチテナント アプリでは acceptMappedClaims プロパティを true に設定しないでください。悪意のある者がアプリのクレームマッピング ポリシーを作成することを許可してしまう場合があります。
要求されたトークンの対象ユーザーは Microsoft Entra テナントの検証済みドメイン名を使用する必要があります。つまり、(アプリケーション マニフェスト内で Application ID URI
によって表される) identifierUris
を例えば https://contoso.com/my-api
または、(単に既定のテナント名を使用して) https://contoso.onmicrosoft.com/my-api
に設定する必要があります。
検証済みのドメインを使用していない場合、Microsoft Entra ID は AADSTS501461
エラー コードを、"_AcceptMappedClaims は、アプリケーション GUID と一致するトークン対象ユーザー、またはテナントの検証済みドメイン内の対象ユーザーでのみサポートされます。 リソース識別子を変更するか、アプリケーション固有の署名キーを使います。
クレームの詳細オプション
同じクレームを SAML トークンとして公開するには、OIDC アプリケーションに対してクレームの詳細オプションを構成します。 また、SAML2.0 と OIDC の両方の応答トークンに同じクレームを使用するアプリケーションについても同様です。
[要求の管理] ブレードの [ 詳細要求オプション ] の下にあるチェック ボックスをオンにして、詳細 要求 オプションを構成します。