要求変換規則言語
フォレスト間要求変換機能を使用すると、フォレスト間の信頼に要求変換ポリシーを設定することで、フォレストの境界を越えてダイナミック アクセス制御の要求をブリッジできます。 すべてのポリシーの主要なコンポーネントは、要求変換規則言語で記述される規則です。 このトピックでは、この言語の詳細について説明し、要求変換規則の作成に関するガイダンスを提供します。
フォレスト間の変換ポリシーの Windows PowerShell コマンドレットには、一般的なシナリオで必要な単純なポリシーを設定するためのオプションがあります。 これらのコマンドレットは、ユーザー入力を要求変換規則言語のポリシーと規則に変換し、指定された形式で Active Directory に格納します。 要求変換のコマンドレットの詳細については、「ダイナミック アクセス制御の AD DS コマンドレットに関するページを参照してください。
要求の構成と、Active Directory フォレスト内のフォレスト間の信頼に設定される要件によっては、要求変換ポリシーが、Active Directory の Windows PowerShell コマンドレットでサポートされているポリシーよりも複雑になる可能性があります。 このようなポリシーを効果的に作成するには、要求変換規則の言語構文とセマンティクスを理解する必要があります。 Active Directory のこの要求変換規則言語 ("言語") は、同様の目的で Active Directory フェデレーション サービス (AD FS) によって使用される言語のサブセットであり、構文とセマンティクスが非常によく似ています。 ただし、Active Directory バージョンの言語では、使用できる操作が少なく、追加の構文制限が適用されます。
このトピックでは、Active Directory の要求変換規則言語の構文とセマンティクス、およびポリシーを作成するときに必要な考慮事項について簡単に説明します。 使用を開始するためのいくつかの規則の例と、正しくない構文とそのために生成されるメッセージの例を示し、規則を作成するときにエラー メッセージを解読できるようにします。
要求変換ポリシーを作成するためのツール
Active Directory 用の Windows PowerShell コマンドレット: これは、要求変換ポリシーを作成して設定する場合に推奨される方法です。 これらのコマンドレットは、単純なポリシー用のスイッチを提供し、より複雑なポリシーに設定されている規則を検証します。
LDAP: 要求変換ポリシーは、ライトウェイト ディレクトリ アクセス プロトコル (LDAP) を使用して Active Directory で編集できます。 ただし、ポリシーには複数の複雑なコンポーネントが含まれていて、使用するツールで Active Directory に書き込む前にポリシーが検証されない可能性があるので、これはお勧めできません。 その後で、問題の診断にかなりの時間が必要な場合があります。
Active Directory 要求変換規則言語
構文の概要
次に言語の構文とセマンティクスの概要を示します。
要求変換規則セットは、0 個以上の規則で構成されます。 各規則には、条件の選択の一覧とルール アクションという 2 つのアクティブな部分があります。 条件の選択の一覧が TRUE に評価された場合は、対応するルール アクションが実行されます。
条件の選択の一覧には 0 個以上の条件の選択があります。 条件の選択の一覧が TRUE に評価されるには、すべての条件の選択が TRUE に評価される必要があります。
各条件の選択には、0 個以上の一致の条件のセットがあります。 条件の選択が TRUE に評価されるには、すべての一致の条件が TRUE に評価される必要があります。 1 つの要求に対してこれらのすべての条件が評価されます。 条件の選択に一致する要求は、識別子によってタグ付けし、ルール アクションで参照できます。
各一致の条件で、異なる条件演算子と文字列リテラルを使用して、要求の Type、Value、または ValueType に一致する条件を指定します。
Value に一致の条件を指定する場合は、特定の ValueType の一致の条件も指定する必要があります。その逆の場合も同じです。 これらの条件は、構文で互いに隣り合っている必要があります。
ValueType の一致の条件では、特定の ValueType リテラルのみを使用する必要があります。
ルール アクションでは、識別子でタグ付けされた 1 つの要求をコピーするか、識別子または指定された文字列リテラルでタグ付けされた要求に基づいて 1 つの要求を発行できます。
規則の例
この例では、2 つのフォレスト間で要求の種類を変換するために使用できる規則を示します。ただし、それらは同じ要求 ValueTypes を使用し、この種類の要求値に対して同じ解釈を持っている必要があります。 規則には、1 つの一致の条件と、文字列リテラルと一致する要求の参照を使用する 1 つの Issue ステートメントが含まれます。
C1: [TYPE=="EmployeeType"]
=> ISSUE (TYPE= "EmpType", VALUE = C1.VALUE, VALUETYPE = C1.VALUETYPE);
[TYPE=="EmployeeType"] == Select Condition List with one Matching Condition for claims Type.
ISSUE (TYPE= "EmpType", VALUE = C1.VALUE, VALUETYPE = C1.VALUETYPE) == Rule Action that issues a claims using string literal and matching claim referred with the Identifier.
ランタイム操作
規則を効果的に作成するには、要求変換のランタイム操作を理解することが重要です。 ランタイム操作では、次の 3 つの要求のセットが使用されます。
入力要求セット: 要求変換操作に渡される要求の入力セット。
ワーキング要求セット: 要求変換中に読み取りおよび書き込みされる中間要求。
出力要求セット: 要求変換操作の出力。
次にランタイム要求変換操作の概要を示します。
要求変換の入力要求は、ワーキング要求セットを初期化するために使用されます。
各規則を処理する場合は、ワーキング要求セットが入力要求に対して使用されます。
規則の条件の選択の一覧は、ワーキング要求セットから取得できるすべての要求セットと照合されます。
一致する要求の各セットは、その規則で操作を実行するために使用されます。
ルール アクションを実行すると、1 つの要求が生成され、出力要求セットとワーキング要求セットに追加されます。 したがって、規則からの出力は、規則セット内の後続の規則の入力として使用されます。
規則セット内の規則は、最初の規則から順番に処理されます。
規則セット全体が処理される場合、出力要求セットが処理されて、重複する要求が削除され、その他のセキュリティの問題が発生します。結果として得られる要求は、要求変換プロセスの出力です。
以前の実行時の動作に基づいて、複雑な要求変換を記述できます。
例: ランタイム操作
この例では、2 つの規則を使用する要求変換のランタイム操作を示します。
C1:[Type=="EmpType", Value=="FullTime",ValueType=="string"] =>
Issue(Type=="EmployeeType", Value=="FullTime",ValueType=="string");
[Type=="EmployeeType"] =>
Issue(Type=="AccessType", Value=="Privileged", ValueType=="string");
Input claims and Initial Evaluation Context:
{(Type= "EmpType"),(Value="FullTime"),(ValueType="String")}
{(Type= "Organization"),(Value="Marketing"),(ValueType="String")}
After Processing Rule 1:
Evaluation Context:
{(Type= "EmpType"),(Value="FullTime"),(ValueType="String")}
{(Type= "Organization"), (Value="Marketing"),(ValueType="String")}
{(Type= "EmployeeType"),(Value="FullTime"),(ValueType="String")}
Output Context:
{(Type= "EmployeeType"),(Value="FullTime"),(ValueType="String")}
After Processing Rule 2:
Evaluation Context:
{(Type= "EmpType"),(Value="FullTime"),(ValueType="String")}
{(Type= "Organization"),(Value="Marketing"),(ValueType="String")}
{(Type= "EmployeeType"),(Value="FullTime"),(ValueType="String")}
{(Type= "AccessType"),(Value="Privileged"),(ValueType="String")}
Output Context:
{(Type= "EmployeeType"),(Value="FullTime"),(ValueType="String")}
{(Type= "AccessType"),(Value="Privileged"),(ValueType="String")}
Final Output:
{(Type= "EmployeeType"),(Value="FullTime"),(ValueType="String")}
{(Type= "AccessType"),(Value="Privileged"),(ValueType="String")}
特別な規則のセマンティクス
次に規則の特別な構文を示します。
空の規則セット == 出力要求なし
空の条件の選択の一覧 == すべての要求が条件の選択の一覧と一致します
例: 空の条件の選択の一覧
次の規則は、ワーキング セット内のすべての要求と一致します。
=> Issue (Type = "UserType", Value = "External", ValueType = "string")
空の一致の選択の一覧 == すべての要求が条件の選択の一覧と一致します
例: 空の一致の条件
次の規則は、ワーキング セット内のすべての要求と一致します。 これは、単独で使用される場合の基本的な "すべて許可" 規則です。
C1:[] => Issule (claim = C1);
セキュリティに関する考慮事項
フォレストに入る要求
フォレストで受信するプリンシパルによって提示される要求は、適切な要求のみを許可または発行するために、十分に検査する必要があります。 要求が不適切な場合、フォレストのセキュリティが損なわれる可能性があります。これは、フォレストに入る要求の変換ポリシーを作成する際の最も重要な考慮事項です。
Active Directory には、フォレストに入る要求の構成ミスを防ぐための次の機能があります。
フォレストの信頼に、フォレストに入る要求に対する要求変換ポリシーが設定されていない場合、セキュリティ上の目的で、Active Directory はフォレストに入るすべてのプリンシパル要求を削除します。
フォレストに入る要求に対して規則セットを実行した結果として、フォレストで定義されていない要求が生成された場合、未定義の要求は出力要求から削除されます。
フォレストから出る要求
フォレストから出る要求は、フォレストに入る要求よりも、フォレストのセキュリティに関する懸念事項が少なくなります。 要求は、対応する要求変換ポリシーが適用されていない場合でも、フォレストから出ることを許可されます。 フォレストから出る要求の変換の一環として、フォレストで定義されていない要求を発行することもできます。 これは、要求を使用してフォレスト間の信頼を簡単に設定するようにするためです。 管理者は、フォレストに入る要求を変換する必要があるかどうかを判断し、適切なポリシーを設定できます。 たとえば、情報漏えいを防ぐために要求を非表示にする必要がある場合、管理者はポリシーを設定できます。
要求変換規則の構文エラー
特定の要求変換ポリシーに構文的に正しくない規則が設定されている場合、または他の構文または記憶域の問題がある場合、ポリシーは無効と見なされます。 これは、前述の既定の条件とは異なる方法で処理されます。
この場合、Active Directory は、意図を特定できず、フェールセーフ モードになります。このモードでは、その信頼とトラバーサルの方向に対する出力要求は生成されません。 この問題を修正するには、管理者の介入が必要です。 これは、LDAP を使用して要求変換ポリシーを編集する場合に発生する可能性があります。 Active Directory 用の Windows PowerShell コマンドレットには、構文に問題があるポリシーの記述を防ぐための検証機能があります。
その他の言語に関する考慮事項
この言語に特別なキー ワードまたは文字がいくつかあります (ターミナルと呼ばれます)。 これらについては、このトピックの後の「言語ターミナル」の表で説明します。 エラー メッセージでは、あいまいさを解消するためにこれらのターミナルのタグが使用されます。
ターミナルは、文字列リテラルとして使用できる場合があります。 ただし、このような使用は言語定義と競合や、意図しない結果を招く可能性があります。 このような使用は推奨されません。
規則アクションは要求の値に対してどのような型変換も実行できません。また、このようなルール アクションを含む規則セットは無効と見なされます。 これによりランタイム エラーが発生し、出力要求は生成されません。
ルール アクションが、ルールの条件の選択の一覧部分で使用されていない識別子を参照している場合は、その使用方法は無効です。 これにより、構文エラーが発生します。
例: 誤った識別子の参照 次の規則は、ルール アクションで使用されている誤った識別子を示しています。
C1:[] => Issue (claim = C2);
変換規則のサンプル
特定の種類のすべての要求を許可する
正確な型
C1:[type=="XYZ"] => Issue (claim = C1);
正規表現の使用
C1: [type =~ "XYZ*"] => Issue (claim = C1);
特定の要求の種類を禁止する 正確な型
C1:[type != "XYZ"] => Issue (claim=C1);
正規表現の使用
C1:[Type !~ "XYZ?"] => Issue (claim=C1);
ルール パーサー エラーの例
要求変換規則は、構文エラーを確認するためにカスタム パーサーによって解析されます。 Active Directory に規則を格納する前に、このパーサーが、関連する Windows PowerShell コマンドレットによって実行されます。 構文エラーを含め、ルールの解析中のすべてのエラーがコンソールに出力されます。 ドメイン コントローラーも、要求を変換するための規則を使用する前にパーサーを実行し、イベント ログにエラーを記録します (イベント ログ番号が追加されます)。
このセクションでは、誤った構文を使用して記述された規則と、パーサーによって生成されるそれに対応する構文エラーの例をいくつか示します。
例:
c1;[]=>Issue(claim=c1);
この例では、コロンの代わりに誤ってセミコロンが使用されています。 エラー メッセージ:POLICY0002: Could not parse policy data.Line number: 1, Column number: 2, Error token: ;. Line: 'c1;[]=>Issue(claim=c1);'.Parser error: 'POLICY0030: Syntax error, unexpected ';', expecting one of the following: ':' .'
例:
c1:[]=>Issue(claim=c2);
この例では、コピー発行ステートメントの識別子タグが未定義です。 エラー メッセージ: POLICY0011: No conditions in the claim rule match the condition tag specified in the CopyIssuanceStatement: 'c2'.
例:
c1:[type=="x1", value=="1", valuetype=="bool"]=>Issue(claim=c1)
"bool" は言語のターミナルではなく、有効な ValueType ではありません。 有効なターミナルが、次のエラー メッセージに一覧表示されます。 エラー メッセージ:POLICY0002: Could not parse policy data. Line number: 1, Column number: 39, Error token: "bool". Line: 'c1:[type=="x1", value=="1",valuetype=="bool"]=>Issue(claim=c1);'. パーサー エラー: 'POLICY0030: Syntax error, unexpected 'STRING', expecting one of the following: 'INT64_TYPE' 'UINT64_TYPE' 'STRING_TYPE' 'BOOLEAN_TYPE' 'IDENTIFIER'
例:
c1:[type=="x1", value==1, valuetype=="boolean"]=>Issue(claim=c1);
この例の数字 1 は、言語の有効なトークンではなく、一致条件ではこのような使用は許可されません。 文字列にするには、二重引用符で囲む必要があります。 エラー メッセージ:POLICY0002: Could not parse policy data.Line number: 1, Column number: 23, Error token: 1. Line: 'c1:[type=="x1", value==1, valuetype=="bool"]=>Issue(claim=c1);'.Parser error: 'POLICY0029: Unexpected input.
例:
c1:[type == "x1", value == "1", valuetype == "boolean"] => Issue(type = c1.type, value="0", valuetype == "boolean");
この例では、1 つの等号 (=) ではなく、二重等号 (==) が使用されています。 エラー メッセージ:POLICY0002: Could not parse policy data.Line number: 1, Column number: 91, Error token: ==. Line: 'c1:[type=="x1", value=="1",valuetype=="boolean"]=>Issue(type=c1.type, value="0", valuetype=="boolean");'.Parser error: 'POLICY0030: Syntax error, unexpected '==', expecting one of the following: '='
例:
c1:[type=="x1", value=="boolean", valuetype=="string"] => Issue(type=c1.type, value=c1.value, valuetype = "string");
これは、構文的およびマンティクス的に正しい例です。 ただし、文字列値として "boolean" を使用すると混乱が生じる可能性があるので、回避する必要があります。 前述のように、要求の値として言語ターミナルを使用することは、可能な限り避ける必要があります。
言語ターミナル
次の表に、要求変換規則言語で使用される、すべてのターミナル文字列のセットと関連する言語ターミナルの一覧を示します。 これらの定義では、大文字と小文字を区別しない UTF-16 文字列が使用されます。
String | ターミナル |
---|---|
IMPLY | |
SEMICOLON | |
COLON | |
COMMA | |
DOT | |
O_SQ_BRACKET | |
C_SQ_BRACKET | |
O_BRACKET | |
C_BRACKET | |
EQ | |
NEQ | |
REGEXP_MATCH | |
REGEXP_NOT_MATCH | |
ASSIGN | |
AND | |
"issue" | 問題 |
"type" | TYPE |
"value" | 値 |
"valuetype" | VALUE_TYPE |
"claim" | CLAIM |
"[_A-Za-z][_A-Za-z0-9]*" | IDENTIFIER |
"\"[^\"\n]*\"" | STRING |
"uint64" | UINT64_TYPE |
"int64" | INT64_TYPE |
"string" | STRING_TYPE |
"boolean" | BOOLEAN_TYPE |
言語の構文
次の要求変換規則言語は、ABNF 形式で指定されています。 この定義では、ここで定義されている ABNF プロダクションに加えて、前の表で指定したターミナルを使用します。 規則は UTF-16 でエンコードする必要があります。文字列比較は大文字と小文字を区別しないものとして扱う必要があります。
Rule_set = ;/*Empty*/
/ Rules
Rules = Rule
/ Rule Rules
Rule = Rule_body
Rule_body = (Conditions IMPLY Rule_action SEMICOLON)
Conditions = ;/*Empty*/
/ Sel_condition_list
Sel_condition_list = Sel_condition
/ (Sel_condition_list AND Sel_condition)
Sel_condition = Sel_condition_body
/ (IDENTIFIER COLON Sel_condition_body)
Sel_condition_body = O_SQ_BRACKET Opt_cond_list C_SQ_BRACKET
Opt_cond_list = /*Empty*/
/ Cond_list
Cond_list = Cond
/ (Cond_list COMMA Cond)
Cond = Value_cond
/ Type_cond
Type_cond = TYPE Cond_oper Literal_expr
Value_cond = (Val_cond COMMA Val_type_cond)
/(Val_type_cond COMMA Val_cond)
Val_cond = VALUE Cond_oper Literal_expr
Val_type_cond = VALUE_TYPE Cond_oper Value_type_literal
claim_prop = TYPE
/ VALUE
Cond_oper = EQ
/ NEQ
/ REGEXP_MATCH
/ REGEXP_NOT_MATCH
Literal_expr = Literal
/ Value_type_literal
Expr = Literal
/ Value_type_expr
/ (IDENTIFIER DOT claim_prop)
Value_type_expr = Value_type_literal
/(IDENTIFIER DOT VALUE_TYPE)
Value_type_literal = INT64_TYPE
/ UINT64_TYPE
/ STRING_TYPE
/ BOOLEAN_TYPE
Literal = STRING
Rule_action = ISSUE O_BRACKET Issue_params C_BRACKET
Issue_params = claim_copy
/ claim_new
claim_copy = CLAIM ASSIGN IDENTIFIER
claim_new = claim_prop_assign_list
claim_prop_assign_list = (claim_value_assign COMMA claim_type_assign)
/(claim_type_assign COMMA claim_value_assign)
claim_value_assign = (claim_val_assign COMMA claim_val_type_assign)
/(claim_val_type_assign COMMA claim_val_assign)
claim_val_assign = VALUE ASSIGN Expr
claim_val_type_assign = VALUE_TYPE ASSIGN Value_type_expr
Claim_type_assign = TYPE ASSIGN Expr