3.6.2.2 テンプレート文字列での割り当て
アイデンティティプロバイダーマッピング画面ではIdPのユーザー情報とOps Iのユーザー情報のマッピング規則を設定します。テンプレート文字列で割り当てると、条件の値、Claim(OIDCの場合)、および属性(SAMLの場合)と、Ops Iのグループ、ロール、および属性が完全に一致しない場合もマッピング対象として指定できます。その結果、マッピングを複数登録しなくても、さまざまな条件を満たす対象を一度に設定できます。
ここでは次の項目について説明します。
(1)記載ルール、例
テンプレート文字列での割り当てには、ディレクティブ、出力式、条件式、演算子、文字列向け関数、シーケンス向け関数が使用できます。
ここで、varは任意の変数、strは任意の文字列、listは任意のシーケンスを意味します。
【ディレクティブ】
使用できるディレクティブは次の通りです。
| ディレクティブ | 説明 | 使用例 |
|---|---|---|
| <#-- コメント --> | コメントの記載 | <#-- コメント --> |
| <#if>...</#if> <#if>...<#elseif>...<#else>...</#if> |
条件分岐 | <#if>...<#elseif>...<#else>...</#if> |
| <#assign var = "A"> | 変数を定義 | <#assign var = "A"> |
| <#list items as item>...</#list> | listの中の値に個別処理を定義 | <#list items as item>...</#list> |
【出力式】
使用できる出力式は次の通りです。
| 出力式 | 説明 | 使用例 |
|---|---|---|
| ${} | 変数を出力 | ${} |
【条件式】
使用できる条件式は次の通りです。
| 条件式 | 説明 | 使用例 |
|---|---|---|
| var?? | 変数が存在するかどうかを確認 | var?? |
| var?has_content | 変数が存在し、かつその値が空でないかどうかを確認 | var?has_content |
【演算子】
使用できる演算子は次の通りです。
| 演算子 | 説明 | 使用例 |
|---|---|---|
| == | 等しい | == |
| ! | 否定 | ! |
| != | 等しくない | != |
| || | または | || |
| && | かつ | && |
| lt | <(未満) | lt |
| lte | <=(以下) | lte |
| gt | >(超過) | gt |
| gte | >=(以上) | gte |
【文字列向け関数】
使用できる文字列向け関数は次の通りです。
| 文字列向け関数 | 説明 | 使用例 |
|---|---|---|
| str?c_lower_case | 小文字にそろえる | str?c_lower_case |
| str?c_upper_case | 大文字にそろえる | str?c_upper_case |
| str?replace("A", "B") | Aの文字列をBの文字列に置き換える | str?replace("A", "B") |
| str?split("A") | 指定した文字列をAで分割し、リスト型で出力 | str?split("A") |
| str?date("yyyy-MM-dd") | 日付型に変換し、演算子ltやgtで日付を比較 | str?date("yyyy-MM-dd") |
| str?number | 数値型に変換 | str?number |
| str?trim | 前後の空白を削除 | str?trim |
| str?contains("A") | 文字列にAを含むかどうかを確認 | str?contains("A") |
| str?starts_with("A") | 文字列がAで始まるかどうかを確認 | str?starts_with("A") |
| str?ends_with("A") | 文字列がAで終わるかどうかを確認 | str?ends_with("A") |
| str?matches("A") | Aの形式の正規表現になっているかどうかを確認 | str?matches("A") |
【シーケンス(配列、リスト)向け関数】
使用できるシーケンス向け関数は次の通りです。
| シーケンス向け関数 | 説明 | 使用例 |
|---|---|---|
| list?seq_contains("A") | シーケンスが特定の要素Aを含むかどうかを確認 | list?seq_contains("A") |
| list?join("A") | シーケンスの要素をAで結合し、単一の文字列を出力 | list?join("A") |
IdPのユーザー情報を参照する場合に使用します。
SAMLとOIDCではauthn_infoで使用できるユーザー情報と使用方法が異なります。それぞれのauthn_infoの特徴は次の通りです。
①SAMLの場合:
- Attributeに含まれる情報を使用できる。
テンプレートによるマッピングでは、AttributeのNameをキーとして、対応する値を配列としてauthn_infoに格納する。単一の値の場合も配列として扱う。例:IdPの情報「preferred_username」が「test_user」に等しい場合
<#if authn_info["preferred_username"][0]=="test_user"> - 配列のどの要素の値を実際に利用するかを指定したい場合にのみ、インデックス(例:[0])で参照する。
例:${authn_info["email"][0]}
複数要素を持つ場合には[0]以外に[1]なども指定できる。以下の場合はインデックスの指定は不要。- 存在確認(??)や空判定(?has_content)などの条件式:
配列の要素ではなく式全体に対して記述しているため - 配列向け(シーケンス向け)の関数:
配列としてauthn_infoに格納されるため
例:authn_info["groups"]?seq_contains("admin")
- 存在確認(??)や空判定(?has_content)などの条件式:
注意事項
- 必要がないときにインデックスの指定をするとエラーが表示されます。
- IdP側からの格納順が不明なため、?seq_contains()などの使用を推奨します。
②OIDCの場合:
- IDトークンまたはUserInfoエンドポイントから取得できるユーザー情報に含まれるプロパティを使用できる
<#if authn_info["preferred_username"]=="test_user">
注意事項
- ユーザー属性に「顧客」を設定する場合、顧客IDを指定してください。
「顧客」を設定する場合は、必ず、以下のいずれかのロールを割り当ててください。- Pre-Installedロール「Customer Manager」
- Pre-Installedロール「Customer User」
- Primitiveロール「customer」および「free_user」
- Primitiveロール「customer」および「manager」
- 上記のいずれかを関連ロールに設定したカスタムロール
- 1つの属性とのマッピング設定を複数作成しないでください。
マッピングされる順序は不定のため、属性の設定値が意図した値にならないことがあります。 - キーの階層構造はブラケット記法で記載してください。
例:上位階層[下位階層] - グループ属性、ロール属性は複数指定できます。このとき、指定する値は改行で区切ってください。また、ユーザー属性は2つ以上指定することがないため、複数指定しないでください。
- テンプレートで指定可能な上限文字数は10,000文字です。
- テンプレートで出力可能な上限文字数は10,000文字です。10,000文字以上出力された場合、エラーメッセージが出力されログインできません。その場合、Ops I セキュリティ管理者はループ処理を中心にテンプレート文字列を見直してください。
- 先頭、および末尾の空白は削除されます。
- ディレクティブの中では、ダブルクォーテーション(")やシングルクォーテーション(')で文字列を囲ってください。
- ディレクティブの外では、ダブルクォーテーション(")やシングルクォーテーション(')で文字列を囲まないでください。意図しない割り当てとなってしまうおそれがあります。
- authn_infoから返される数値は、数値型ではなく、文字列型であることがあります。文字列型の場合、数値型で使用できる操作を行えません。
- 出力式「${}」は、ディレクティブの中では使用しないでください。
ディレクティブ、出力式、条件式、演算子、文字列向け関数、シーケンス向け関数を使用した例は以下の通りです。
「改行付きでロールを出力」というコメントを記載
<#if authn_info["role"]??>
${authn_info["role"]?join("\n")}
</#if>
<#if>...<#elseif>...<#else>...</#if>
IdPの「id」が「1」の場合は「adminGroup1」を、「2」の場合は「adminGroup2」を、それ以外の場合は「customerGroup」のロールを割り当てる
adminGroup1
<#elseif authn_info["id"] == "2">
adminGroup2
<#else>
customerGroup
</#if>
IdPの「department」が「abc」という文字列でない場合、「portal_subscriber」ロールを割り当てる
<#if !condition1>
portal_subscriber
</#if>
<#list items as item>...</#list>
リスト型で格納されているIdPの「role」情報をそれぞれ確認し、文字列の一部に「admin」という文字列が含まれている場合、「user_admin」と「customer_admin」を割り当てる
<#if rolename?contains("admin")>
user_admin
customer_admin
</#if>
</#list>
IdP側の「email」情報が空でない場合、「email」情報をそのまま割り当てる
${authn_info["email"]}
</#if>
IdP連携をしている場合、「idp_user」グループを割り当てる
idp_user
</#if>
IdP側の「email」情報が空でない場合、「email」情報をそのまま割り当てる
${authn_info["email"]}
</#if>
IdPの「groups」以下の「customer.group」が「portal」という文字列である場合、「portal_subscriber」ロールを割り当てる
portal_subscriber
</#if>
IdPの「department」が「abc」という文字列でない場合、「portal_subscriber」ロールを割り当てる
<#if !condition1>
portal_subscriber
</#if>
IdPの「customer」が「123」という文字列でない場合、「customer_group」グループを割り当てる
customer_group
</#if>
IdPの「groups」がリストの中に「group 1」を持つか、「role」がリストの中に「author」を持つ場合、「portal_author」ロールを割り当てる
portal_author
</#if>
IdPの「groups」がリストの中に「group 2」を持ち、かつ「email」が「abc.com」である場合、「portal_site_admin」ロールを割り当てる
portal_site_admin
</#if>
IdPの文字列型だが数値である「customer(顧客コード)」を数値型に変換し、それが2000より小さい場合、「customer_group」グループを割り当てる
customer_group
</#if>
IdPの文字列型だが数値である「customer(顧客コード)」を数値型に変換し、それが2000以下の場合、「customer_group」グループを割り当てる
customer_group
</#if>
IdPの文字列型だが数値である「customer(顧客コード)」を数値型に変換し、それが2000より大きい場合、「customer_group」グループを割り当てる
customer_group
</#if>
IdPの文字列型だが数値である「customer(顧客コード)」を数値型に変換し、それが2000以上の場合、「customer_group」グループを割り当てる
customer_group
</#if>
IdPの「username」を小文字に変換し、それが「hitachi_taro」と等しい場合、「customer_admin」ロールを割り当てる
customer_admin
</#if>
IdPの「username」を大文字に変換し、それが「HITACHI_TARO」と等しい場合、「customer_admin」ロールを割り当てる
customer_admin
</#if>
IdPの「groups」以下の「customer.group」が「hitachi」という文字列を含んでいる場合、その名前の「hitachi」部分を「test」に置き換えた名前のロールを割り当てる
${authn_info["groups"]["customer.group"]?replace("hitachi", "test")}
</#if>
IdPに「name」情報があり、かつその値が空でなく、「" "」で区切られている場合、それで区切った初めの値を姓として扱う
${authn_info["name"]?split(" ")[0]}
</#if>
IdPの生年月日情報(yyyy-MM-ddの形で格納されている)が2000年1月1日より前である場合、「century_group」グループを割り当てる
century_group
</#if>
IdPの文字列型だが数値である「customer(顧客コード)」を数値型に変換し、それが2000より大きい場合、「customer_group」グループを割り当てる
customer_group
</#if>
IdPの顧客情報が空でない情報を持っており、値が2000と等しい場合、「idp_user」グループを割り当てる
idp_user
</#if>
IdPの「email」が「hitachi」という文字列を含む場合、「hitachi_group」グループを割り当てる
hitachi_group
</#if>
IdPの「username」が「admin」という文字列で始まっている場合、「itsm_admin」ロールを割り当てる
itsm_admin
</#if>
IdPの「email」が「.com」という文字列で終わっている場合、IdPの「email」をOps Iの「email」として用いる
${authn_info["email"]}
</#if>
IdPの「customer(顧客コード)」が数字で構成されている場合、その顧客コードを割り当てる
${authn_info["customer"]}
</#if>
IdPで複数ロールを持つうちの1つに「admin」ロールを持っている場合、「itsm_admin」ロールを割り当てる
itsm_admin
</#if>
IdPに「role」情報がある場合、その同名ロールをOps Iで割り当てる
${authn_info["role"]?join("\n")}
</#if>
(2)アイデンティティプロバイダー設定時のエラー
アイデンティティプロバイダーの設定やテンプレートの記載に不備がある場合、以下のタイミングでエラーが出力されます。
【アイデンティティプロバイダーの保存時】
文法上の誤りがある場合、アイデンティティプロバイダーの保存時にエラーメッセージが表示されます。
エラーメッセージに記載された「[詳細]」を確認することで、問題のある行を特定できます。
<例>
構文エラーがある場合
KNBA00300-E
[詳細] エラーが発生した行
【ユーザーがログインするとき】
ロールの割り当て時に、該当するロールが存在しない場合
グループの割り当て時に、該当するグループが存在しない場合
顧客の割り当て時に、該当する顧客が存在しない場合、該当する顧客が[無効]または[無効-暫定]の場合
顧客の有効/無効状態については「JP1 Cloud Service 運用統合 利用ガイド(ITSM操作編)」の「[顧客]>[顧客管理]>顧客登録」を参照してください。
1つのユーザー属性に複数の値が割り当てられようとしている場合
メールアドレスの割り当て時に、予約ユーザーのメールアドレスが割り当てられようとしている場合
必須属性※に空の値が割り当てられようとしている場合
テンプレートで出力可能な上限文字数である10,000文字を超えた場合
不備の内容によって、以下のメッセージが出力されます。割り当てられるメールアドレスの認証の流れは「(図)IdPとOps Iに同一と判断されるユーザーが存在する場合に、IdPでログインする」を参照してください。
(3)よくある間違い
テンプレートの記載でよくある間違いと正しい記載の例を以下に示します。
- 顧客を指定する場合、顧客名ではなく顧客IDで指定してください。
<誤><#if authn_info["customer"] == "customer1"><正>
customer1
</#if><#if authn_info["customer"] == "customer1">
1001
</#if> - グループを割り当てる場合、改行で指定してください。
<誤><#if authn_info["group"]??><正>
${authn_info["group"]}
</#if><#if authn_info["group"]??>
${authn_info["group"]?join("\n")}
</#if> - ロールを割り当てる場合、改行で指定してください。
<誤><#if authn_info["id"] == "1"><正>
System Security Administrator, user_admin
</#if><#if authn_info["id"] == "1">
System Security Administrator
user_admin
</#if> - SAMLの場合、配列の中のどの要素を参照するか、インデックスで指定してください。
- テンプレートで属性(顧客)を割り当てる場合
<誤><#if authn_info["customer"] == "customer1"><正>
1001
</#if><#if authn_info["customer"][0] == "customer1">
1001
</#if> - テンプレートでロールを割り当てる場合
<誤><#if authn_info["username"]?c_upper_case == "HITACHI_TARO"><正>
customer_admin
</#if><#if authn_info["username"][0]?c_upper_case == "HITACHI_TARO">
customer_admin
</#if>
- テンプレートで属性(顧客)を割り当てる場合