다음을 통해 공유


클레임 변환 규칙 언어

포리스트 간 클레임 변환 기능을 사용하면 포리스트 간 트러스트에서 클레임 변환 정책을 설정하여 포리스트 경계를 넘어 동적 Access Control에 대한 클레임을 연결할 수 있습니다. 모든 정책의 기본 구성 요소는 클레임 변환 규칙 언어로 작성된 규칙입니다. 이 주제에서는 해당 언어에 대한 세부 정보를 제공하고 클레임 변환 규칙 작성 지침을 제공합니다.

포리스트 간 트러스트 변환 정책에 대한 Windows PowerShell cmdlet에는 일반적인 시나리오에서 필요한 간단한 정책을 설정하는 옵션이 있습니다. 이러한 cmdlet은 사용자 입력을 클레임 변환 규칙 언어의 정책 및 규칙으로 변환한 다음 지정된 형식으로 Active Directory에 저장합니다. 클레임 변환을 위한 cmdlet에 관한 자세한 내용은 동적 액세스 제어용 AD DS Cmdlet을 참조하세요.

Active Directory 포리스트의 포리스트 간 트러스트에 대한 클레임 구성 및 요구 사항에 따라 클레임 변환 정책이 Active Directory용 Windows PowerShell cmdlet에서 지원하는 정책보다 복잡해야 할 수도 있습니다. 이러한 정책을 효과적으로 작성하려면 클레임 변환 규칙 언어 구문 및 의미 체계를 이해해야 합니다. Active Directory의 이 클레임 변환 규칙 언어('언어')는 유사한 용도로 Active Directory Federation Services에서 사용하는 언어의 하위 집합이며 구문과 의미 체계가 매우 유사합니다. 그러나 허용하는 작업이 적고 언어의 Active Directory 버전에 추가 구문 제한이 적용됩니다.

이 주제에서는 Active Directory에서 클레임 변환 규칙 언어의 구문과 의미 체계를 간략하게 설명하고 정책 작성 시 고려해야 할 사항을 설명합니다. 규칙을 작성할 때 오류 메시지를 해독하는 데 도움이 되는 몇 가지 예제 규칙 집합과 잘못된 구문 및 생성되는 메시지의 예를 제공합니다.

클레임 변환 정책 작성 도구

Active Directory용 Windows PowerShell cmdlet: 클레임 변환 정책을 작성하고 설정하는 기본 설정 및 권장 방법입니다. 이러한 cmdlet은 간단한 정책에 대한 스위치를 제공하고 더 복잡한 정책에 관하여 설정된 규칙을 확인합니다.

LDAP: Claims transformation policies can be edited in Active Directory through Lightweight Directory Access Protocol (LDAP). 그러나 정책에는 몇 가지 복잡한 구성 요소가 있으며, 사용하는 도구가 Active Directory에 쓰기 전에 정책의 검증하지 못할 수 있으므로 권장되지 않습니다. 이로 인해 추후 문제 진단에 상당한 시간이 필요할 수 있습니다.

Active Directory 클레임 변환 규칙 언어

Syntax overview

다음은 언어의 구문 및 의미 체계에 대한 간략한 개요입니다.

  • 클레임 변환 규칙 집합은 0개 이상의 규칙으로 구성됩니다. 각 규칙에는 조건 목록 선택규칙 작업이라는 두 개의 활성 부분이 있습니다. 조건 목록 선택이 TRUE로 평가되면 해당 규칙 작업이 실행됩니다.

  • 조건 선택 목록조건 선택이 0개 이상입니다. All of the Select Conditions must evaluate to TRUE for the Select Condition List to evaluate to TRUE.

  • Each Select Condition has a set of zero or more Matching Conditions. All the Matching Conditions must evaluate to TRUE for the Select Condition to evaluate to TRUE. 이러한 모든 조건은 단일 클레임에 대해 평가됩니다. A claim that matches a Select Condition can be tagged by an Identifier and referred to in the Rule Action.

  • Each Matching Condition specifies the condition to match the Type or Value or ValueType of a claim by using different Condition Operators and String Literals.

    • When you specify a Matching Condition for a Value, you must also specify a Matching Condition for a specific ValueType and vice versa. 이러한 조건은 구문에서 서로 옆에 있어야 합니다.

    • ValueType matching conditions must use specific ValueType literals only.

  • A Rule Action can copy one claim that is tagged with an Identifier or issue one claim based on a claim that is tagged with an Identifier and/or given String Literals.

Example rule

이 예제에서는 동일한 클레임 ValueType을 사용하고 이 유형의 클레임 Value에 대해 동일한 해석을 갖는 경우 두 포리스트 간에 클레임 Type 변환에 사용할 수 있는 규칙을 보여 줍니다. 규칙에는 문자열 리터럴과 일치하는 클레임 참조를 사용하는 하나의 일치 조건과 발급 문이 있습니다.

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.

Runtime operation

규칙을 효과적으로 작성하려면 클레임 변환의 런타임 작업을 이해하는 것이 중요합니다. 런타임 작업은 다음 세 가지 클레임 집합을 사용합니다.

  1. 입력 클레임 집합: 클레임 변환 작업에 지정된 클레임의 입력 집합입니다.

  2. 작업 클레임 집합: 클레임 변환 중에 읽고 쓰는 중간 클레임입니다.

  3. 출력 클레임 집합: 클레임 변환 작업의 출력입니다.

런타임 클레임 변환 작업에 대한 간략한 개요는 다음과 같습니다.

  1. 클레임 변환에 대한 입력 클레임은 작업 클레임 집합 초기화에 사용합니다.

    1. 각 규칙을 처리할 때 작업 클레임 집합을 입력 클레임에 사용합니다.

    2. 규칙의 선택 조건 목록은 작업 클레임 집합에서 가능한 모든 클레임 집합과 일치합니다.

    3. 일치하는 각 클레임 집합은 해당 규칙에서 작업을 실행하는 데 사용됩니다.

    4. 규칙 작업을 실행하면 하나의 클레임이 생성되며 출력 클레임 집합 및 작업 클레임 집합에 추가됩니다. 따라서 규칙의 출력을 규칙 집합의 후속 규칙에 대한 입력으로 사용합니다.

  2. 규칙 집합의 규칙은 첫 번째 규칙부터 순차적으로 처리합니다.

  3. 전체 규칙 집합이 처리되면 중복 클레임 및 기타 보안 문제를 제거하기 위해 출력 클레임 집합을 처리합니다. 결과 클레임은 클레임 변환 프로세스의 출력입니다.

이전 런타임 동작에 따라 복잡한 클레임 변환을 작성할 수 있습니다.

예제: 런타임 작업

이 예제에서는 두 규칙을 사용하는 클레임 변환의 런타임 작업을 보여 줍니다.


     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")}

특수 규칙 의미 체계

다음은 규칙에 대한 특수 구문입니다.

  1. 빈 규칙 집합 == 출력 클레임 없음

  2. 빈 선택 조건 목록 == 모든 클레임이 조건 선택 목록과 일치

    예제: 빈 조건 목록 선택

    다음 규칙은 작업 집합의 모든 클레임과 일치합니다.

    => Issue (Type = "UserType", Value = "External", ValueType = "string")
    
  3. 빈 일치 선택 목록 == 모든 클레임이 조건 선택 목록과 일치

    예제: 빈 일치 조건

    다음 규칙은 작업 집합의 모든 클레임과 일치합니다. 이 규칙은 단독으로 사용되는 경우 기본 'Allow-all' 규칙입니다.

    C1:[] => Issule (claim = C1);
    

Security considerations

포리스트를 입력하는 클레임

포리스트에 들어오는 보안 주체가 제시한 클레임을 철저히 검사하여 올바른 클레임만 허용하거나 발급해야 합니다. 부적절한 클레임은 포리스트 보안을 훼손할 수 있으며 포리스트에 진입하는 클레임에 대한 변환 정책을 작성할 때 이를 최우선으로 고려해야 합니다.

Active Directory에는 포리스트에 들어가는 클레임의 잘못된 구성을 방지하는 다음과 같은 기능이 있습니다.

  • 포리스트 트러스트에 포리스트를 입력하는 클레임에 대해 설정된 클레임 변환 정책이 없는 경우 Active Directory는 보안 목적으로 포리스트에 들어가는 모든 주체 클레임을 삭제합니다.

  • 포리스트를 입력하는 클레임에서 규칙 집합을 실행하면 포리스트에 정의되지 않은 클레임이 생성되었을 때 정의되지 않은 클레임이 출력 클레임에서 삭제됩니다.

포리스트를 유지하는 클레임

포리스트를 유지하는 클레임은 포리스트에 들어가는 클레임보다 포리스트에 대한 보안 문제가 적습니다. 클레임은 해당 클레임 변환 정책이 없는 경우에도 포리스트를 있는 그대로 둘 수 있습니다. 포리스트를 유지하는 클레임 변환의 일부로 포리스트에 정의되지 않은 클레임을 발급할 수도 있습니다. 이는 클레임을 사용하여 포리스트 간 트러스트를 쉽게 설정하기 위한 것입니다. 관리자는 포리스트에 진입하는 클레임을 변환해야 하는지 여부를 확인하고 적절한 정책을 설정할 수 있습니다. 예를 들어 정보 공개 방지를 위해 클레임을 숨겨야 하는 경우 관리자가 정책을 설정할 수 있습니다.

클레임 변환 규칙의 구문 오류

지정된 클레임 변환 정책에 구문이 잘못된 규칙 집합이 있거나 다른 구문 또는 스토리지 문제가 있는 경우 정책은 잘못된 것으로 간주됩니다. 이때는 앞에서 설명한 기본 조건과 다르게 처리됩니다.

Active Directory는 이 경우 의도를 확인할 수 없으며 장애 조치 모드로 전환됩니다. 이 모드에서는 해당 트러스트+방향 순회에 대해 출력 클레임이 생성되지 않습니다. 문제를 해결하려면 관리자의 개입이 필요합니다. 이는 LDAP를 사용하여 클레임 변환 정책을 편집하는 경우에 발생할 수 있습니다. Active Directory용 Windows PowerShell cmdlet에는 구문 문제가 있는 정책 작성을 방지하기 위한 검증 절차가 있습니다.

기타 언어 관련 고려 사항

  1. 이 언어에서 특수한 몇 가지 키워드 또는 문자가 있습니다. 이를 터미널이라고 합니다. These are presented in the Language terminals table later in this topic. 오류 메시지는 명확하도록 이러한 터미널에 대한 태그를 사용합니다.

  2. 터미널을 문자열 리터럴로 사용할 수 있습니다. 단, 이러한 사용은 언어 정의와 충돌하거나 의도하지 않은 결과를 초래할 수 있습니다. 이러한 종류의 사용은 권장되지 않습니다.

  3. 규칙 작업은 클레임 값에서 형식 변환을 수행할 수 없으며 이러한 규칙 동작이 포함된 규칙 집합은 잘못된 것으로 간주됩니다. 이로 인해 런타임 오류가 발생하고 출력 클레임이 생성되지 않습니다.

  4. 규칙 동작이 규칙의 조건 목록 선택 부분에서 사용되지 않은 식별자를 참조하는 경우, 이는 잘못된 사용입니다. 이로 인해 구문 오류가 발생합니다.

    예제: 잘못된 식별자 참조 다음 규칙은 규칙 동작에 사용된 잘못된 식별자를 보여 줍니다.

    C1:[] => Issue (claim = C2);
    

샘플 변환 규칙

  • 특정 유형의 모든 클레임 허용

    Exact type

    C1:[type=="XYZ"] => Issue (claim = C1);
    

    Using Regex

    C1: [type =~ "XYZ*"] => Issue (claim = C1);
    
  • 특정 클레임 형식 허용 안 함 정확한 형식

    C1:[type != "XYZ"] => Issue (claim=C1);
    

    Using Regex

    C1:[Type !~ "XYZ?"] => Issue (claim=C1);
    

규칙 파서 오류 예제

클레임 변환 규칙은 구문 오류를 확인하기 위해 사용자 지정 파서에 따라 파싱합니다. 이 파서는 Active Directory에 규칙을 저장하기 전에 관련 Windows PowerShell cmdlet에서 실행합니다. 구문 오류를 포함하여 규칙을 파싱하는 모든 오류가 콘솔에 출력됩니다. 또한 도메인 컨트롤러는 클레임 변환 규칙을 사용하기 전에 파서도 실행하며 이벤트 로그에 이벤트 로그 번호를 추가하여 오류를 기록합니다.

이 섹션에서는 잘못된 구문으로 작성된 규칙과 파서에서 생성된 해당 구문 오류의 몇 가지 예제를 살펴봅니다.

  1. Example:

    c1;[]=>Issue(claim=c1);
    

    이 예제에는 콜론 대신 잘못 사용되는 세미콜론이 있습니다. Error message: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: ':' .'

  2. Example:

    c1:[]=>Issue(claim=c2);
    

    이 예제에서는 사본 발급 문의 식별자 태그가 정의되지 않았습니다. Error message: POLICY0011: No conditions in the claim rule match the condition tag specified in the CopyIssuanceStatement: 'c2'.

  3. Example:

    c1:[type=="x1", value=="1", valuetype=="bool"]=>Issue(claim=c1)
    

    'bool'은 언어의 터미널이 아니며 유효한 ValueType이 아닙니다. 유효한 터미널은 다음 오류 메시지에 나열됩니다. Error message:POLICY0002: Could not parse policy data. Line number: 1, Column number: 39, Error token: "bool". 줄: 'c1:[type=="x1", value=="1", valuetype=="bool"]=>Issue(claim=c1);'. 파서 오류: 'POLICY0030: 구문 오류, 예기치 않게 'STRING'이 입력되었으며, 'INT64_TYPE' 'UINT64_TYPE' 'STRING_TYPE' 'BOOLEAN_TYPE' 'IDENTIFIER' 중 하나가 예상됩니다.

  4. Example:

    c1:[type=="x1", value==1, valuetype=="boolean"]=>Issue(claim=c1);
    

    The numeral 1 in this example is not a valid token in the language, and such usage is not allowed in a matching condition. 문자열로 만들려면 큰따옴표(")로 묶어야 합니다. Error message: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.

  5. Example:

    c1:[type == "x1", value == "1", valuetype == "boolean"] =>
    
         Issue(type = c1.type, value="0", valuetype == "boolean");
    

    이 예제에서는 단일 등호(=) 대신 이중 등호(==)를 사용했습니다. Error message: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: '='

  6. Example:

    c1:[type=="x1", value=="boolean", valuetype=="string"] =>
    
          Issue(type=c1.type, value=c1.value, valuetype = "string");
    

    이 예제는 구문과 의미 체계가 올바릅니다. 단, 문자열 값으로 'boolean'을 사용하면 혼동을 일으킬 수 있으므로 피해야 합니다. 앞서 언급했듯이 가능한 경우 언어 터미널을 클레임 값으로 사용해서는 안 됩니다.

Language terminals

다음 표에는 클레임 변환 규칙 언어에 사용되는 터미널 문자열 및 관련 언어 터미널의 전체 집합이 나와 있습니다. 이러한 정의는 대/소문자를 구분하지 않는 UTF-16 문자열을 사용합니다.

String Terminal
"=>" 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" ISSUE
"type" TYPE
"value" 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

Language syntax

다음 클레임 변환 규칙 언어는 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