オープンソース・ソリューション・テクノロジ株式会社
Open Source Solution Technology Corporation

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」型のオブジェクトが自動的に生成されます。

https://git.shibboleth.net/view/?p=java-identity-provider.git;a=blob_plain;f=idp-attribute-api/src/main/java/net/shibboleth/idp/attribute/IdPAttribute.java;hb=HEAD

処理の記載方法

値の受け取り

内部の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>