この章では、Identity Governance Framework ArisID API (ArisID API)のアーキテクチャと主要な機能について説明します。ArisID APIは、エンタープライズ開発者とシステム設計者に、複数のアイデンティティ・プロトコルを使用したアイデンティティ対応のアプリケーションを作成するためのライブラリを提供します。ArisID APIでは、開発者は、Client Attribute Requirements Markup Language (CARML)を使用して、アイデンティティの属性、ロールおよび検索フィルタの要件を指定できます。
この章の内容は次のとおりです。
Identity Governance Framework ArisID APIは、すべてのアイデンティティ情報交換の受渡しに使用される共通のコア・サービスを表します。正式な名称ではありませんが、ArisID APIは、開発者からアイデンティティBeanと呼ばれることが多くあります。
12c (12.1.3)リリースのArisID APIは、次に提案されている構成のサブセットです。
http://www.openliberty.org/wiki/index.php/ArisID_Configuration
.
Oracle WebLogic ServerとOracle Identity Managementをインストールしてある場合、このAPIを使用したアプリケーションの開発に必要なjarファイルはすべて、コンピュータにすでにインストールされています。
Identity Governance Frameworkオープン・ソースAPI jarファイルは次のとおりです。
openliberty.arisId_1.1.jar: 属性のセットを含むアイデンティティ・サブジェクトの取得に使用されるライブラリ関数とプロバイダを含んだコアArisID APIを提供します。詳細は、http://arisid.sourceforge.net/javadocs/arisId_1.1_javadoc/
を参照してください。
org.openliberty.arisIdBeans_1.1.jar: ArisID APIに加えてJavaオブジェクトの抽象化を提供するArisID Beanを提供します。これらによって、ArisID APIのトランザクション型アプローチをオブジェクトまたはBean型のアプローチに変換します。詳細は、http://arisid.sourceforge.net/javadocs/arisId_1.1_javadoc/
を参照してください。
ArisID API jarファイルは次のとおりです。
idxuserrole.jar: 標準的なユーザーとロールのアイデンティティの読取り専用操作を提供します。このjarは、標準のidxuserrole.xml CARMLファイルから生成されます。詳細は、Identity Governance Framework IDXUserRole Java APIリファレンスを参照してください。
userrole.jar: アイデンティティ情報を更新するためのユーザーとロールのアイデンティティ読取り/書込み操作を提供します。詳細は、Identity Governance Framework UserRole Java APIリファレンスを参照してください。
arisId-stack-ovd.jar: このjarファイルはOracle Virtualizationライブラリを使用したIAttrSvcStack
インタフェースの実装で、異なるバックエンドに接続し、アイデンティティ・ストア・エンティティの抽象ビューを提供します。
ArisID Beanによって、CARML対話の初期化とアクセスに必要なJava APIが提供されます。Beanジェネレータでは、Apache Velociyを使用してCARMLファイル内の各エンティティに対するjavaファイルのセットを生成します。CARMLファイルは、アプリケーションの属性使用要件を記述する宣言型のドキュメントです。ArisID Beanは、jarファイルidxuserrole.jarおよびuserrole.jar内にあります。
次の図に、ArisID APIアーキテクチャの概要を示します。
Identity Governance Framework ArisIDでは、作成 > 変更 > テスト > デプロイといった基本的な開発プロセスがサポートされます。作成では、CARML XMLファイルをご使用の環境に応じて変更する必要があります。アプリケーションのテストは、LDAPディレクトリ・サーバーが組み込まれたOracle WebLogic Serverで行えます。
この項では、次の項目について説明します。
CARMLファイルidxuserrole.xml(読取り専用操作)とuserrole.xml(読取り専用および読取り/書込み操作)を確認して、既存のArisID Beanがアプリケーションのニーズを満たすかどうかを判断します。これらのファイルは、DOMAIN_HOME/config/fmwconfig/carmlにあります。
ArisID Beanによって使用されるアイデンティティ・リポジトリを使用可能にする必要があります。LDAPベースのディレクトリ・サーバーが組み込まれたOracle WebLogic Serverまたは11gのOracle Virtual Directoryでサポートされている任意のLDAPディレクトリを使用できます。ArisID APIは、Oracle Platform Security Servicesと統合されています。Oracle Platform Security Servicesに構成されているLDAPベースのアイデンティティ・ストアに自動的に接続します。Oracle Platform Security Servicesでサポートされているアイデンティティ・ストアの詳細は、第1.3項「システム要件と動作保証情報」を参照してください。
Oracle Platform Security Servicesの詳細は、『Oracle Platform Security Servicesによるアプリケーションの保護』を参照してください。
Oracle Platform Security Servicesアイデンティティ・ストアとは異なるアイデンティティ・ストアを使用する必要がある場合、次のシステム・プロパティを設定します。
igf.ovd.config.dir=DOMAIN_HOME/config/fmwconfig/arisidprovider/conf
次に、adapters.os_xmlファイルを編集して、接続先のディレクトリのhost
、port
および資格証明を含めます。igf.ovd.config.dir
プロパティは、adapaters.os_xmlおよび適切に設定された他の構成ファイルを含む任意のディレクトリに設定できます。
ディレクトリ制限
次のLDAPディレクトリ制限が適用されます。
OpenLDAP 2.2またはNovell eDirectoryを使用する場合、ページングはサポートされていません。たとえば、searchUsersbyPage()
、searchRolesbyPage()
などのページングAPIは機能しません。複数言語サポート(MLS)は提供されません。
Oracle WebLogic Serverの組込みLDAPベースのディレクトリ・サーバーを使用する場合、複数言語サポート(MLS)は提供されません。
CARMLファイルが作成されている場合、対応するマッピング・ファイルは同じ場所に作成されます。デフォルトのマッピング・ファイルには、Oracle WebLogic Serverに組み込まれているディレクトリ・サーバー(Oracle Platform Security Servicesのデフォルト・アイデンティティ・ストア)に固有の属性詳細が含まれています。デフォルトのCARMLファイルとOracle Platform Security Servicesアイデンティティ・ストアを使用する場合、マッピングを構成する必要ばありません。Oracle Platform Security Servicesの構成パラメータは、マッピング・ファイルのパラメータをオーバーライドします。
デフォルトのCARMLファイルとマッピング・ファイルには、デプロイ・シナリオについて特定の想定がなされています。デプロイ要件によっては、これらの詳細を変更する必要がある場合があります。この項では、変更可能な構成パラメータについて説明します。
この項では、次の項目について説明します。
デフォルトの構成では、ユーザー・エントリを識別するための一意の識別子としてemail
が使用されます。ユーザーの検索時、検索に想定されているデフォルトの属性はemail
です。次に例を示します。
SearchUser( String uniqueid, Map<String, Object>)
パフォーマンス上の理由から、一意の識別子として使用される属性は、バックエンドで検索可能な属性である必要があります。アプリケーションが選択したuniquekey
とバックエンドの属性との間のマッピングは、構成時に処理されます。これは、Oracle Virtual Directoryマッピングでの構成です。HashMap
を使用して、操作の実行時に使用するオプションのコンテキスト情報を指定します。現在のリリースでは、次のオプションがサポートされます。
検索を実行するプリンシパル・ユーザー: (ArisIdConstants.APP_CTX_AUTHUSER, (Principal)user
)
言語の制約(ある場合): (ArisIdConstants.APP_CTX_LOCALE, "fr"
)
ページネーション・サポート(ある場合): (ArisIdConstants.APP_CTX_PAGESIZE, 10
)
アプリケーションで、アイデンティティ・リポジトリのバックエンドからアクセスされるエントリをアプリケーション固有のリポジトリに格納することがあります。このような場合、永続化する属性を慎重に検討する必要があります。たとえば、バックエンドがLDAPベースのリポジトリの場合、GUID
属性がLDAPベースのバックエンドで唯一の一意のキーであるため、永続化属性としてこれを使用します。他のLDAP属性はすべて変更可能です。
バックエンドがリレーショナル・データベースの場合、一意性制約が適用される属性を一意キーとして選択します。これは、ArisIDマッピング・プロパティ・ファイルで指定できます。一意キーに基づいてユーザーを検索するメソッドは次のとおりです。
searchUserOnUniqueKey(String UniqueKey, Map<String,Object>)
HashMap
を使用して、操作の実行時に使用するオプションのコンテキスト情報を指定します。現在のリリースでは、次のオプションがサポートされます。
検索を実行するプリンシパル・ユーザー: (ArisIdConstants.APP_CTX_AUTHUSER, (Principal)user
)
言語の制約(ある場合): (ArisIdConstants.APP_CTX_LOCALE, "fr"
)
ページネーション・サポート(ある場合): (ArisIdConstants.APP_CTX_PAGESIZE, "10"
)
ロケール固有の結果を必要とするアプリケーション向けに複数言語サポート(MLS)が提供されます。属性と適切なMLSコードは、ArisIDプロパティ・ファイルのmultiLanguageAttributes
要素に格納されます。
<multiLanguageAttributes>…</multiLanguageAttribute>
displayname
は、最もよく使用される複数言語属性であるため、デフォルトで複数言語属性として構成されています。必要に応じて他の属性をArisIDマッピング・ファイルに追加できます。
制限
引数としてロケールが指定されるAPIでは、ArisIDプロパティ・ファイルに<multiLanguageAttributes>
としてリストされている、ロケール固有の値を持つすべての属性に対してロケール固有の値が返されます。他の属性についてはすべて、格納されているデフォルト値が返されます。
バックエンドのシステムでは、データはISO-3166に準拠した形式で返されます。たとえば、(英語の他に)フランス語のロケールがある場合、cn
属性に対してcn,:fr
として格納されます。クライアント・アプリケーションのロケールは、プロパティHashMap
にArisIdConstants.APP_CTX_LOCALE, "fr"
と指定し、ArisIDプロパティ・ファイルにcn
をmultiLanguageAttribute
として含め、この属性をマップします。
アプリケーションでアイデンティティ・データにアクセスする場合、検索の結果セットが大きすぎてアプリケーションで処理できない場合があります。そのような場合、管理可能なサイズのページに結果を分割することができます。これは、ページで返されるオブジェクトの数を定義することで行います。
次の例に、標準的な使用法を示します。
RoleManager rm = new RoleManager(env); List<PropertyFilterValue> attrFilters = new ArrayList<PropertyFilterValue>(); attrFilters.add(new PropertyFilterValue(Role.NAME, "admin", AttributeFilter.OP_CONTAINS)); HashMap<String,Object> map = new HashMap<String,Object>(); map.put("ArisIdConstants.APP_CTX_PAGESIZE","2"); SearchResults<Role> sr = rm.searchRolesbyPage(attrFilters, map); while(sr.hasMore()) { List<Role> roles = sr.getNextSet(); for (int i=0; i<roles.size(); i++) //do the operations with roles.get(i) }
ターゲット・システムでの作成、読取り、更新および削除(CRUD)操作の実行に2つのセキュリティ・シナリオを使用できます。これらを次に示します。
ドメイン・レベルの資格証明
アプリケーション・レベルの資格証明
このリリースでは、プロキシ認証はサポートされていません。
このシナリオでは、ドメイン内のすべてのアプリケーションで共通の資格証明を使用してターゲット・システムに接続し、その資格証明で操作を実行します。アプリケーションは、ターゲット・システムにフットプリントを保持しません。
LDAPアダプタの構成ファイルadapters.os_xml
には、バックエンド・ディレクトリに接続するための資格証明およびホストとポートの詳細が含まれています。初期化時に他の資格証明を指定しない場合、アプリケーションはLDAPアダプタの構成ファイル内の資格証明を使用してターゲット・システムに接続します。
プロキシ・ユーザー(ログイン・ユーザーID)がAPIのアプリケーション・コンテキストで指定されていない場合、ArisID操作は、LDAPアダプタの構成ファイル内にある資格証明を使用して実行されます。
アプリケーションが共通の資格証明を使用して接続する場合、認可されたユーザーについてのみデータを表示したり、変更するようアプリケーション自体にセキュリティを組み込む必要があります。
例3-1 コード・サンプル: adapters.os_xml
LDAPアダプタの構成ファイルadapters.os_xml
は、バックエンド・ディレクトリへの接続にドメイン・レベルのユーザーIDと暗号化されたパスワードを使用するよう構成されています。次に示すのは、adapters.os_xml
のスニペットです。
<binddn>cn=admin</binddn> <bindpass>{OMASK}C2QXW1Nmf+s=</bindpass>
ArisID APIの初期化時、資格証明を指定しません。
Map env = new HashMap(); // Do not set UserManager.SECURITY_PRINCIPAL & SECURITY_CREDENTIALS UserManager uMgr = new UserManager(env); … … // Search Operation (with no proxy user in app context) List<PropertyFilterValue> attrFilters = new ArrayList<PropertyFilterValue>(); attrFilters.add(new PropertyFilterValue("User.FIRSTNAME", "app1", AttributeFilter.OP_CONTAINS)); attrFilters.add(new PropertyFilterValue("User.LASTNAME", "user1", AttributeFilter.OP_BGNSWITH)); Map<String, Object> appCtx = null; users = um.searchUsers(attrFilters, appCtx);
このシナリオでは、各アプリケーションでアプリケーション・レベルの資格証明を使用してターゲット・システムに接続し、その資格証明でCRUD操作を実行します。
この場合、ArisID APIの初期化時にアプリケーションのユーザーIDとパスワードを指定します。そうすると、アプリケーションはそれらの資格証明を使用してターゲット・システムに接続します。
プロキシ・ユーザーがAPIのアプリケーション・コンテキストに指定されていない場合、アプリケーションの資格証明を使用してArisID操作が実行されます。
この使用例には、次の機能があります。
各アプリケーションは、ターゲット・システムのデータの表示および更新を行うための異なる権限を持ちます。
ターゲット・システムで各アプリケーションによって行われる変更を監査できます。
例3-2 コード・サンプル: adapters.os_xml
LDAPアダプタの構成ファイルadapters.os_xml
は、バックエンド・ディレクトリへの接続にドメイン・レベルのユーザーIDと暗号化されたパスワードを使用するよう構成されています。次に示すのは、adapters.os_xml
のスニペットです。
<binddn>cn=admin</binddn> <bindpass>{OMASK}C2QXW1Nmf+s=</bindpass>
ArisID APIの初期化時、アプリケーションのユーザー資格証明を指定します。
Map env = new HashMap(); env.put(UserManager.SECURITY_PRINCIPAL, "cn=app1_user,cn=users,dc=example,dc=com"); env.put(UserManager.SECURITY_CREDENTIALS, "mypassword"); UserManager uMgr = new UserManager(env); … // Search Operation (with no proxy user in app context) List<PropertyFilterValue> attrFilters = new ArrayList<PropertyFilterValue>(); attrFilters.add(new PropertyFilterValue("User.FIRSTNAME", "app1", AttributeFilter.OP_CONTAINS)); attrFilters.add(new PropertyFilterValue("User.LASTNAME", "user1", AttributeFilter.OP_BGNSWITH));Map<String, Object> appCtx = null; users = um.searchUsers(attrFilters, appCtx);
デフォルトの接続/読取りタイムアウトは15秒に設定されています。たとえば、IdentityStore
のLDAP操作に15秒以上かかる場合、その操作はタイムアウトし、IGFでは次の例外が発生します。
org.openliberty.arisid.stack.ConnectionException
IdentityStore
に多数のエントリがあり、「次を含む」というフィルタを使用してページング/ソートで検索すると、これらの問合せはタイムアウトする場合があります。
タイムアウト値を0(タイムアウトなし)に設定し、プール・サイズを20まで増やすことをお薦めします。アプリケーションにタイムアウト間隔がある場合は、0より大きい値を設定します。
タイムアウト間隔を構成する手順は、次のとおりです。
次のWLSTコマンドを実行し、すべてのアダプタをリストします。
listAdapters()
各アダプタに対して次のコマンドを実行し、timeout
およびmaxpoolsize
を設定します。
modifyLDAPAdapter('<ADAPTER NAME>', 'OperationTimeout', 0)
modifyLDAPAdapter('<ADAPTER NAME>', 'MaxPoolSize', 20)
WebLogic Serverを再起動します。
ArisID Beanを次のように生成します。
java BeanGenerator [-genmap] <package name> <output dir> [<relationship file>] <carml file>
ここで、
-genmap
は、CARMLファイルと同じ場所にCARML-ArisIDStack
マップ・ファイルを生成します。
package name
は、生成されたBeanクラスのパッケージ名です。
output dir
は、生成されたBeanクラスの書込み先です。
relationship file
は、エンティティ間のリレーションシップ定義を含むファイルです。
carml file
は、CARML宣言ファイルです。
CARMLファイルからORG
Beanをビルドする手順は次のとおりです。
ORG
エンティティ用の適切な属性または相互作用を指定する、CARMLファイル名org.xmlを作成します。
Beanジェネレータを使用して、org
Bean(OrgManager.java
およびOrg.java
)を生成します。build.xmlファイルの内容は、次のサンプルのようになります。
<path id="ArisIDBeans.classpath"> <pathelement location="MW_HOME/oracle_common/modules/velocity-dep-1.4.jar" /> <pathelement location="MW_HOME/oracle_common/modules/oracle.jrf_11.1.1/jrf.jar" /> </path> <property name="BeanGeneratorClassPath" refid="ArisIDBeans.classpath"/> <target name="generatebeans" description="generate arisid beans"> <java classname="org.openliberty.arisidbeans.BeanGenerator" dir="${generatedsource.dir}" fork="true"> <arg value="${generatedbean.userrole.packagename}"/> <arg value="."/> <arg value="${carml.dir}/org.xml"/> <classpath> <pathelement path="${BeanGeneratorClassPath}"/> </classpath> <sysproperty key="org.openliberty.arisid.policy.wspolicy.class" value="org.openliberty.arisid.policy.neethi.PolicyImpl" /> </java> </target>
生成されたJavaファイル(Org.java
およびOrgManager.java
)をコンパイルします。
生成されたマッピング・ファイル(igf-map-config-.xml)を編集して、basesearch
、objectclass
、OVD
属性名でそれぞれの値を更新します。
アプリケーションでは、CARMLファイル(org.xml)に定義されている相互作用用の生成されたORG
APIを使用できます。アプリケーションをアプリケーション・サーバーにデプロイした後で、次の作業を行います。
マッピング・ファイルをDOMAIN_HOME/config/fmwconfig/arisidprovider/confにコピーします。
CARMLファイルをDOMAIN_HOME/config/fmwconfig/carmlにコピーします。
次のサンプル・アプリケーションでは、IDXユーザー/ロールBeanを使用します。
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <%@page import="org.openliberty.arisid.*"%> <%@page import="org.openliberty.arisidbeans.*"%> <%@page import="oracle.igf.userrole.*"%> <%@page import="java.util.*"%> <%@page import="java.net.URI"%> <%!public static UserManager uMgr = null; { try { uMgr = new UserManager(null); } catch (Exception e) { e.printStackTrace(); } } %> <html> <head> <title>Search Users</title> <% String firstname = request.getParameter("firstname"); String lastname = request.getParameter("lastname"); String telephone = request.getParameter("telephone"); List<PropertyFilterValue> attrFilters = new ArrayList<PropertyFilterValue>(); attrFilters.add(new PropertyFilterValue("firstname", firstname, AttributeFilter.OP_BGNSWITH)); attrFilters.add(new PropertyFilterValue("lastname", lastname, AttributeFilter.OP_BGNSWITH)); attrFilters.add(new PropertyFilterValue("telephone", telephone, AttributeFilter.OP_CONTAINS)); List<User> subjs = uMgr.searchUsers(attrFilters); %> </head> <body> <a href="SearchUsers.html">Home</a> <center>List of Users with FirstName starting with "<%=firstname%>", LastName starting with "<%=lastname%>" and TelephoneNumber containing "<%=telephone%>"</center> <% Iterator<User> sIter = subjs.iterator(); while (sIter.hasNext()) { User subj = sIter.next(); Map<String, IAttributeValue> vals = subj.getAllAttributes(); Iterator<IAttributeValue> iter = vals.values().iterator(); %> <table border="0"> <tr> <th>Item</th> <th>Value</th> </tr> <% while (iter.hasNext()) { IAttributeValue val = iter.next(); String name = val.getNameIdRef(); String value = null; if (val.size() > 0) value = val.get(0); if (value != null) { %> <tr> <td><%=name%></td> <td><%=value%></td> </tr> <% } } %> </table> <% } %> <br> <br> <br> <a href="SearchUsers.html">Home</a> </body> </html>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <HTML> <HEAD><TITLE>Search Users</TITLE></HEAD> <BODY> <FORM METHOD=POST ACTION="SearchUsers.jsp"> First Name Starting with <INPUT TYPE=TEXT NAME=firstname SIZE=30><BR><BR> Last Name Starting with <INPUT TYPE=TEXT NAME=lastname SIZE=30><BR><BR> Telephone Number containing <INPUT TYPE=TEXT NAME=telephone SIZE=15><BR><BR> <P><INPUT TYPE=SUBMIT> </FORM> </BODY> </HTML>
OpenLDAPの場合、Role.MEMBER
は次のAPIに必須の属性です。
createRole(List<PropertyValue> attrVals, Map<String,Object> appCtxMap)
createRole(List<PropertyValue> attrVals)
入力attrVals
リストにRole.MEMBER
が含まれていない場合、ロールの作成は失敗します。