Shibboleth IdP で ScriptedAttribute を利用する方法
2021-03-11 - 鈴木 慶太
Shibboleth IdP でのスクリプトによる属性生成
概要
Shibboleth IdP では、SPへの属性送出の際、スクリプトによる生成機能があります。 公式のドキュメントはありますが(https://wiki.shibboleth.net/confluence/display/IDP4/ScriptedAttributeDefinition)、ドキュメントをみても肝心のJavascriptエンジン部分に対する説明がなく、使い方がよくわかりません。 今回は、スクリプトによる生成を行う際の、処理の記載方法について記載します。
設定箇所
attribute-resolver.xmlで指定します。
※ attribute-filter.xml でもスクリプト処理を組み込むことができますが、こちらは送出の制限を組み込むべき定義であるため、送出属性の生成処理はattribute-filter.xmlに記載するべきではありません。
設定方法
送出する際の属性名の指定
以下の行で、送出する属性の属性名を指定します。 今回の場合は、“eduPersonPrincipalName” の値を生成する指定です。
<AttributeDefinition id="eduPersonPrincipalName" xsi:type="ScriptedAttribute">
...
</AttributeDefinition>
スクリプトの処理であることは、「xsi:type」に"ScriptedAttribute"を指定することで指定します。
生成の際に元にする値の指定
以下の行で、入力属性の属性名を指定します。
以下の指定の場合、「ref=“myLDAP”」でデータストアで指定された “myLDAP” のデータベースからの情報取得を行います。
<InputDataConnector ref="myLDAP" attributeNames="eduPersonPrincipalName uid" />
attributeNamesでは、指定したデータストアから取得する属性の値をスペース区切りで指定します。 今回の場合は、データストア上の"eduPersonPrincipalName", “uid"が取得されます。
値の生成処理の指定
スクリプト処理の記載方法
実際の処理は以下のように記載します。処理部はjavascriptによって記載され、JVM内臓のJavascriptエンジン(Nashornエンジン)により実行されます。 そのため、新しいECMA Scriptの文法は使うことができません。ECMAScript 5.1のJavascriptで処理を記載する必要があります。
※Nashornエンジンは、JVMでは将来的に廃止予定となっており、すでに非推奨です。(http://openjdk.java.net/jeps/335)
<Script>
<![CDATA[
(実際の処理)
]]>
</Script>
入出力値の受け取り
先述の、「送出する際の属性名の指定」「生成の際に元にする値の指定」は、「net.shibboleth.idp.attribute.IdPAttribute」型のオブジェクトが自動的に生成されます。
処理の記載方法
値の受け取り
内部のJavascriptでは、値を受け取りの際に値が存在しなかった場合、オブジェクトが生成されず “undefined” の状態で渡されます。 そのため、 “undefined” 型のオブジェクトかを考慮する必要があります。
if (typeof eduPersonPrincipalName == "undefined") {
}
値の返却
先の「送出する際の属性名の指定」により、自動的に送出予定の属性名で、「net.shibboleth.idp.attribute.IdPAttribute」型でオブジェクトが作成されています。値はaddValueメソッドにより投入することができます。
eduPersonPrincipalName.addValue(eduPersonPrincipalName.getValues().get(0));
最終的なプログラム
今回はuidを受け取りスコープを付与することで、eduPersonPrincipalNameを生成する例です。 処理そのものはJavascriptで自由に記載できるので、より複雑な条件での値生成も可能です。
<AttributeDefinition id="eduPersonPrincipalName" xsi:type="ScriptedAttribute">
<InputDataConnector ref="myLDAP" attributeNames="uid" />
<Script>
<![CDATA[
if (typeof uid == "undefined") {
eduPersonPrincipalName.addValue(new scopedValueType("dummy", "%{idp.scope}");
}else{
eduPersonPrincipalName.addValue(new scopedValueType(uid.getValues.get(0), "%{idp.scope}");
}
]]>
</Script>
</AttributeDefinition>