ヘッダーをスキップ
Oracle® Fusion Middleware Oracle Entitlements Server開発者ガイド
11gリリース2 (11.1.2.2)
B71698-05
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次
索引へ移動
索引

前
 
次
 

7 機能の拡張

Oracle Entitlements Serverランタイム環境に拡張クラスをロードすることで、基本機能を拡張できます。拡張機能はJavaアーカイブ(JAR)ファイルとしてバンドルされています。この章では、作成可能な拡張機能に関する次の項について説明します。

7.1 属性リトリーバの使用

ポリシー情報ポイント(PIP)は、属性値のソースとして機能するシステムエンティティです。ポリシーの実行時評価の間に、Oracle Entitlements Serverは、属性リトリーバ・プラグインを利用して1つ以上のPIP情報ストアから属性値を取得します。これらの属性リトリーバにより、属性の値がアクセスの決定に影響するデータ・ドリブン方式でポリシーを使用できます。たとえば、銀行口座からの送金へのアクセスが現在口座にある金額に基づく場合、属性リトリーバ・コンポーネントを使用して現在の残高を取得できます。このインフラストラクチャは高い拡張性があり、ユーザーは独自のPIPプラグインを開発して、ファイル、USBドライバ、インターネットなど、多くの場所から情報を取得できます。


注意:

PIPの詳細な説明は、『Oracle Fusion Middleware Oracle Entitlements Server管理者ガイド』を参照してください。

詳細は、次の各項を参照してください。

7.1.1 属性リトリーバの理解

Oracle Entitlements Serverは事前定義済属性リトリーバを使用して、Lightweight Directory Access Protocol (LDAP)データ・ストアおよびリレーショナル・データベース管理システム(RDBMS)に接続します。別のタイプのPIPデータ・ストアから属性値を取得するためにカスタム属性リトリーバを開発することができます。カスタム属性リトリーバは、1つまたは多数の属性に値を返せます。

属性リトリーバの構成情報は、jps-config.xml構成ファイルで定義されます。このファイル内の属性リトリーバの構成は、事前定義済とカスタムによって異なります。

  • 事前定義済属性リトリーバの場合:

    • データ・ストアへの接続に必要な情報と資格証明情報を構成します。

    • 属性名、使用する属性リトリーバの名前、値を取得する検索問合せ(たとえば、PIPがリレーショナル・データベースの場合はSQL問合せ、ディレクトリの場合はLDAP問合せ)、および属性値のキャッシング情報など、属性値を個別に構成します。

    事前定義済属性リトリーバの詳細は、『Oracle Fusion Middleware Oracle Entitlements Server管理者ガイド』を参照してください。

  • カスタム属性リトリーバの場合は、属性リトリーバを実装するクラスの名前に関する情報を構成します。

属性リトリーバは、単一の値または複数の値の属性を返すことができます。


注意:

jps-config.xml構成ファイルの詳細は、『Oracle Fusion Middlewareアプリケーション・セキュリティ・ガイド』を参照してください。Oracle Entitlements Server固有のパラメータは、『Oracle Fusion Middleware Oracle Entitlements Server管理者ガイド』を参照してください。

7.1.2 カスタム属性リトリーバの作成

1.3.3項「条件の追加」の説明のとおり、ポリシーの条件は属性または関数を使用して作成します。条件に動的な属性値を使用する場合、属性をcom.bea.security.AppContextインタフェースで渡したり、事前定義済またはカスタム属性リトリーバで取得することができます。次の手順では、カスタム属性リトリーバの作成手順を説明します。

  1. com.bea.security.providers.authorization.asi.AttributeRetrieverV2インタフェースを使用してカスタム属性リトリーバを実装します。

    詳細は、7.1.3項「カスタム属性リトリーバの実装」を参照してください。

  2. JARファイルを作成します。

  3. 次のJARファイルを該当するクラスパスに追加します。

    • Javaセキュリティ・モジュールへ接続する場合は、JARファイルをアプリケーションのクラスパスに追加します。

    • RMI、WebサービスまたはWebLogic Serverセキュリティ・モジュールに接続する場合、他のセキュリティ・モジュールのJARファイルがあるシステムのクラスパスにJARファイルを追加します。

    JARが物理的に格納されている場所は問題にはなりません。

  4. カスタム属性リトリーバを使用するようにセキュリティ・モジュールを構成します。

    構成では、カスタム属性リトリーバの完全修飾の場所を指定してください。詳細は、『Oracle Fusion Middleware Oracle Entitlements Server管理者ガイド』を参照してください。

7.1.3 カスタム属性リトリーバの実装

カスタム属性リトリーバにはAttributeRetrieverV2インタフェースを実装する必要があります。表7-1はこの目的で使用可能なメソッドを説明しています。

表7-1 AttributeRetrieverV2インタフェースのメソッド

メソッド 説明

getAttributeValue()

特定の属性の値が要求されるたびに、このメソッドをコールします。指定された属性の値が返され、次のパラメータが取得されます。

  • Nameは取得する属性の名前を定義します。

  • RequestHandleは、(必要時に)他の属性の値を取得するインタフェースです。また、異なる属性リトリーバ間やカスタム関数間でのコンテキスト(任意のオブジェクト)の共有を可能にします。

  • Subjectは、リクエストに関連付けられたユーザーを定義します。

  • Rolesは、サブジェクトのロール・メンバーシップを定義します。また、ロール・マッピング・コールの場合はNULLになります。

  • Resourceは、リクエストに関連付けられた保護されたリソースを定義します。

  • contextHandlerは、リクエストに関連付けられたコンテキストです。存在しない場合はNULLになることがあります。

getHandledAttributeNames()

このメソッドは、多くの場合、属性リトリーバのロード時に1回コールします。このメソッドは、属性リトリーバが値を戻すことができる属性名のリストを返します。


最も単純な使用方法の場合、属性リトリーバは値の取得に追加情報を必要としません。たとえば、日中の時刻を取得する場合、getAttributeValue()はシステム関数をコールし、情報を返します。他の使用例では、属性リトリーバが属性値を返す前に、追加の情報を必要とする場合があります。たとえば、属性リトリーバはユーザーの場所を取得するためにユーザーの識別子を必要とします。このため、属性リトリーバには、他の属性の値を取得するためにRequestHandleインタフェースが提供されています。この例で、属性リトリーバはRequestHandleインタフェースを使用して組込みのSYS_USER属性の値を取得します。この値は現在のユーザーのアイデンティティに解決されます。


注意:

システム属性の名前は、%sys_user%のようにパーセント記号(%)で囲む必要があります。

次の各項では、属性取得オプションの詳細を説明します。

7.1.3.1 属性値の直接取得

AttributeRetrieverV2の実装では、getAttributeValue()メソッドを使用して名前付き属性の値を返すことができます。このメソッドは、入力に属性の名前を取り、その属性の値を返します。例7-1では、getAttributeValue()の使用方法を示します。

例7-1 getAttributeValue()メソッドの実装

package oracle.security.oes.test;
 
import java.util.Map;
 
import javax.security.auth.Subject;
 
import weblogic.security.service.ContextHandler;
import weblogic.security.spi.Resource;
 
import com.bea.security.providers.authorization.asi.AttributeRetrieverV2;
import com.bea.security.providers.authorization.asi.ARME.evaluator.RequestHandle;
 
public class SimpleAttributeRetriever implements AttributeRetrieverV2 {
 
    public Object getAttributeValue(String name, RequestHandle requestHandle,
         Subject subject, Map roles, Resource resource, 
         ContextHandler contextHandler) {
       if (name == null) return null;
       return "static_value";
    }
 
    public String[] getHandledAttributeNames() {
       return new String[] {"static_attr"};
    }
 
}

MyAttributeRetrieverV2は、AttributeRetrieverV2の実装です。getHandledAttributeNames()メソッドは、この実装で処理される属性の名前を返します。少なくとも1つの属性を返します。空の値やNULL値は、リトリーバが任意の属性でコールされることを意味します。getAttributeValue()パラメータの値は次のように定義されています。

  • nameは取得する属性の名前です。

  • requestHandleは、(必要時に)他の属性の値を取得可能なインタフェースの実装です。また、異なる属性リトリーバ間やカスタム関数間でのコンテキスト(任意のオブジェクト)の共有を可能にします。使用されていない場合も関数に渡されます。

  • subjectは、リクエストに関連付けられたプリンシパルを定義します。

  • rolesは、関連付けられたプリンシパルのロール・メンバーシップを定義します。オブジェクトは、キーがロール名で、値がロール・オブジェクトのマップです。

  • resourceは、リクエストに関連付けられた保護されたリソースです。

  • contextHandlerは、リクエストに関連付けられたコンテキストを定義します。コンテキストが存在しない場合は、NULLになる場合があります。

7.1.3.2 ハンドルを使用した属性値の取得

状況によっては、属性リトリーバが必要な属性値を取得する前に、参考情報として属性の取得が必要になる場合があります。たとえば、属性リトリーバがユーザーの場所を取得するために、ユーザーの属性を必要とする場合があります。RequestHandleインタフェースのgetAttribute()メソッドを呼び出すことにより、属性リトリーバは識別子を取得でき、ユーザーのすべての情報にアクセスできます。getAttribute()メソッドは、AttributeElementオブジェクトの名前と値のペアとして属性名と値を返します。

RequestHandleは、必要時に他の属性の値を取得可能なインタフェースです。また、属性リトリーバやカスタム関数の異なる呼び出し間でコンテキスト(任意のオブジェクト)の共有を可能にします。


注意:

getAttribute()メソッドは、ユーザーとリソース属性の値を取得するために使用します。動的な属性や拡張属性の値を取得するために使用することはできません。

例7-2では、getAttribute()の使用方法を示します。

例7-2 getAttribute()メソッドの使用方法

public Object getAttributeValue
   (String name, RequestHandle requestHandle, Subject subject, 
    Map roles, Resource resource, ContextHandler contextHandler) {

... ...
 
// retrieve sys_user built-in attribute 
   String user = null;
   try {
      AttributeElement element = requestHandle.getAttribute("sys_user", true);
          if (element != null) {
              user = (String)element.getValueAs(String.class);
            }
   } catch (Exception e) {
// ignore it
     }

... ...
}

getAttribute()パラメータの値は次のように定義されています。

  • sys_userは取得する属性の名前です。

  • trueは、属性タイプのチェック機能を有効にします。タイプのチェックを無効にするために、この値をfalseにできます。

7.1.4 カスタム属性リトリーバに対するOracle Entitlements Serverの構成

この項では、カスタム属性リトリーバを認識するためにOracle Entitlements Serverを構成する手順を説明します。com.bea.security.providers.authorization.asi.AttributeRetrieverV2の実装後(7.1.3項「カスタム属性リトリーバの実装」で説明)、Javaコードをコンパイルし、コンパイルしたクラスをセキュリティ・モジュール・インスタンスのクラスパスに追加し、jps-config.xml構成ファイルに次の変更を加えます。

  1. 例7-3に示すようにPIPサービス・プロバイダを<serviceProviders>セクションに宣言します。

    例7-3 jps-config.xmlのserviceProvidersセクション

    <serviceProviders>
       <serviceProvider 
          class="oracle.security.jps.az.internal.runtime.provider.
             PIPServiceProvider" name="pip.service.provider" type="PIP"/>
    </serviceProviders>
    
  2. 例7-4に示すようにPIPサービス・インスタンスを<serviceInstances>セクションに宣言します。

    例7-4 jps-config.xmlのserviceProvidersセクション

    <serviceInstances>
       <serviceInstance name="pip.service.MyAttributeRetriever"
        provider="pip.service.provider">
          <property name="type" value="CUSTOM_PIP"/>
          <property name="application" value="testPIPBasedOnCustomPIP"/>
          <property name="description" value="MyAttributeRetriever"/>
          <property name="classnames" value="pips.MyDummyAttributeRetriever"/>
      </serviceInstance>
    </serviceInstances>
    

    次の表の定義に従ってプロパティを指定します。

    名前
    Type 値はCUSTOM_PIPにする必要があります。
    Application PIPインスタンスが適用されるアプリケーションです。
    Classnames カスタムPIPの完全修飾クラス名です。

  3. 例7-5に示すようにPIPサービス・インスタンスを<jpsContext>セクションに宣言します。

    例7-5 jps-config.xmlのjpsContextセクション

    <jpsContext name="default">
       <serviceInstanceRef ref="pip.service.MyAttributeRetriever"/>
    </jpsContext>
    

7.2 カスタム関数の開発

関数は、ポリシーの条件で高度な処理を実行するために使用できます。関数は、いくつかのパラメータを取り、サポートされている任意のデータ型を戻すことができます。Oracle Entitlements Serverでは、いくつかの事前定義済関数が提供されており、さらに独自の関数を宣言できます。

7.2.1 カスタム関数の実装

次の手順は、ポリシー内にカスタム関数を実装するときに行う詳細手順を示しています。

  1. 関数のカスタム・コードを記述します。例7-6を参照してください。

  2. Javaコードをコンパイルし、jarファイルを作成します。コンパイルされたクラスをクラスパスに追加します。

  3. サーバーを再起動します。

7.2.1.1 手順1. カスタム・コードの記述

カスタム関数は、クラス内にメソッドとして実装でき、メソッドには1つまたは複数のカスタム関数を含めることができます。メソッド名には、ポリシー内で参照している対応する名前と一致していれば、任意の名前を選択できます。カスタム関数は、定数や他の属性(動的属性を含む)または他の関数名で構成された引数を渡すことができます。すべての評価関数が共通のネームスペースを共有するため、2つの関数が同じ名前を持つことはできません。

例7-6は、カスタム関数の作成方法を示しています。

例7-6 カスタム関数のサンプルJava擬似コード

//Package declaration
package oracle.security.oes.extensions;
 
import java.util.Map;
 
 
import javax.security.auth.Subject;
 
import weblogic.security.service.ContextHandler;
import weblogic.security.spi.Resource;
 
import com.bea.security.providers.authorization.asi.ARME.evaluator.RequestHandle;
import com.wles.util.AttributeElement;
 
public class MyCustomFunction {
    
    /** 
     Named evaluation function. Additional authorization request data
     is made available to allow for more complex attribute evaluation.
     This method will be registered to an application and be invoked while 
     the policy contains a custom evaluation function with the name 
     "my_custom_function".
 
     @param requestHandle  an attributes container associated with the request, 
                           through which the function can get required attribute
                           value.
 
     @param args           an array of function arguments. Each element is either
                           <code>null</code> or a String
 
     @param subject        the subject associated with the request
 
     @param roles          the role membership map of the subject
                           key: role name.
                           value: role object <code>null</code> if function 
                           is called during role mapping
 
     @param resource       the resource associated with the request
 
     @param contextHandler the context associated with the request, may be
                           <code>null</code> if non-existent
 
     @return <Return_data_type> as the result of the function
 
     @throws Exception if the function cannot get required attribute value.
     */
    
public <Return_data_type> my_custom_function(RequestHandle requestHandle,
            Object[] args,
            Subject subject,
            Map roles,
            Resource resource,
            ContextHandler contextHandler) {
 
        // Check if we have a correct number of the input paramters
        if(args.length < <required_number_of_attributes> ||
                args[0] == null || args[1] == null) {
            // Incorrect number of arguments.
            // Such a policy is invalid and cannot be evaluated
               throw new RuntimeException
               ("Incorrect number of arguments provided to the function");
        }
 
        // Arguments for an evaluation function are attribute names.
        // If a string literal or a numeric value is used, then
        // it is passed in as value.  The only way to distinguish
        // values from names is to try to look up the attribute.
        // Evaluation function should not set any values.
        try {
 
              //The body of the custom function.
              //It should return the value of the type specified in the method
              //signature. 
                    
            } catch(Exception e) {
            
               //Catch the exception and throw with error message
               throw new RuntimeException(
                    "Detailed error message ...." + " Exception: " + e.getMessage());
        }
        
        return <return_data_type_value>;
    }
    
}

7.2.1.2 手順2.ソース・コードのコンパイルと、クラスのJARファイルへの内包

ソース・コードをコンパイルする手順:

  1. JAVA_HOMEおよびPATHをJVMの場所に基づいて設定します。

  2. コンパイルに含まれるOES jarファイルを含むようにクラスパスを設定します。

  3. コードをコンパイルし、custom_funcs.jarというJARファイルを作成します。

7.2.1.3 手順3.アプリケーションがデプロイされる先のWebLogicドメインのCLASSPATHへのJarファイルの追加

JARファイルをクラスパスに追加する手順:

  1. setDomainEnv.shファイルのコピーを作成します。

  2. JarファイルをPOST_CLASSPATHに追加します。

    POST_CLASSPATH="${POST_CLASSPATH}${CLASSPATHSEP}${ORACLE_HOME}/dist/custom_funcs.jar"export POST_CLASSPATH
    

7.2.1.4 手順4.サーバーの再起動

サーバーを再起動します。

7.2.2 メタデータ情報に対するInspectableFunctionの使用方法

引数メタデータのインタフェースは、カスタムOracle Entitlements Server関数が予期する引数についての情報を問い合せるために使用します。(これには、引数の数と、それらの名前および型などがあります。)オプションで、これらの引数問合せに対してInspectableFunctionインタフェースを実装できます。このインタフェースを基にカスタム関数を追加すると、管理コンソールはgetArgMetadataメソッドをコールして、引数を表すメタデータを返し、カスタム関数が予期するメタデータを検証します。

関数で予期される最初の引数(引数0)ごとに、getArgMetadataは引数を表すメタデータを返す必要があります。管理コンソールで予期される引数ごとのメタデータが収集されると、カスタムOracle Entitlements Server関数を使用するプロセスを自動化するために、インタフェース・メソッドのgetArgValueおよびisValidArgValueが使用されます。

  • 例7-7に、getArgMetadata(String functionName)メソッドのサンプル・コードを示します。

  • 例7-8に、getArgValues (String functionName, int argNumber, ArrayList<oracle.security.jps.service.policystore.info.DataType> prevArgValues)メソッドのサンプル・コードを示します。

  • 例7-9に、isValidArgValue (String functionName, int argNumber, oracle.security.jps.service.policystore.info.DataType argValue, ArrayList<oracle.security.jps.service.policystore.info.DataType> prevArgValues)メソッドのサンプル・コードを示します。

例7-7 getArgMetadata()メソッドのサンプル・コード

public ArrayList<ArgMetadata> getArgMetadata (String functionName) 
{
 if (functionName.compareToIgnoreCase(Constants.GET_STRING_IDC_FUNC_NAME) == 0 ||
 functionName.compareToIgnoreCase(Constants.GET_INTEGER_IDC_FUNC_NAME) == 0 ||
 functionName.compareToIgnoreCase(Constants.GET_BOOLEAN_IDC_FUNC_NAME) == 0) 
 {
ArrayList<ArgMetadata> metadata = new ArrayList<ArgMetadata>();
metadata.add (new ArgMetadata (Constants.GET_IDC_FUNC_ARGS.CLAIM_NAME.ordinal(), 
  "Attribute", OpssString.class, true, false, true));
return metadata;
} else {
  throw new RuntimeException ("Invalid function name " + functionName);
}
}

例7-8 getArgValues()メソッドのサンプル・コード

public ArrayList<oracle.security.jps.service.policystore.info.DataType> 
  getArgValues (String functionName, int argNumber, 
  ArrayList<oracle.security.jps.service.policystore.info.DataType> prevArgValues)
 
throws RuntimeException {
 
ArrayList<oracle.security.jps.service.policystore.info.DataType> values = 
  new ArrayList<oracle.security.jps.service.policystore.info.DataType>();
 
if (functionName.compareToIgnoreCase(Constants.GET_STRING_IDC_FUNC_NAME) == 0 ||
functionName.compareToIgnoreCase(Constants.GET_INTEGER_IDC_FUNC_NAME) == 0 ||
functionName.compareToIgnoreCase(Constants.GET_BOOLEAN_IDC_FUNC_NAME) == 0) 
{
  if (argNumber == Constants.GET_IDC_FUNC_ARGS.CLAIM_NAME.ordinal()) {
 
// return claims in the dictionary
 
Iterator<ClaimSchema> it = dictCtx.getDictionary().getClaimsForAllNamespaces();
 
while (it.hasNext()) {
 
if ((functionName.compareToIgnoreCase(Constants.GET_STRING_IDC_FUNC_NAME) == 
  0 && it.next().getType() == String.class) ||
 
(functionName.compareToIgnoreCase(Constants.GET_INTEGER_IDC_FUNC_NAME) == 
  0 && it.next().getType() == Integer.class) ||
 
(functionName.compareToIgnoreCase(Constants.GET_BOOLEAN_IDC_FUNC_NAME) == 
  0 && it.next().getType() == Boolean.class))
 
{                       
nameList.add (it.next().getUniqueName());
 
 }
 }
  Collections.sort(nameList);
  for (String name : nameList)
   values.add (new OpssString (name));
 
 } else {
 
 throw new RuntimeException ("Invalid argument number " + argNumber);
 
 }
 
 } else {
 
throw new RuntimeException ("Invalid function name " + functionName);
        } 
        return values;
    }

例7-9 isValidArgValue()メソッドのサンプル・コード

public boolean isValidArgValue (String functionName, int argNumber, oracle.security.jps.service.policystore.info.DataType argValue, ArrayList<oracle.security.jps.service.policystore.info.DataType> prevArgValues)
 
throws RuntimeException {
 
if (functionName.compareToIgnoreCase(Constants.GET_STRING_IDC_FUNC_NAME) == 0 ||
 
functionName.compareToIgnoreCase(Constants.GET_INTEGER_IDC_FUNC_NAME) == 0 ||
 
functionName.compareToIgnoreCase(Constants.GET_BOOLEAN_IDC_FUNC_NAME) == 0) {
 
if (argNumber == Constants.GET_IDC_FUNC_ARGS.CLAIM_NAME.ordinal()) 
  {
// is it a valid claim?
try {
ClaimSchema schema = dictCtx.getDictionary().getClaimSchema(argValue.toString());
return ((functionName.compareToIgnoreCase(Constants.GET_STRING_IDC_FUNC_NAME) 
  == 0 && schema.getType() == String.class) ||
 (functionName.compareToIgnoreCase(Constants.GET_INTEGER_IDC_FUNC_NAME) 
  == 0 && schema.getType() == Integer.class) ||
 (functionName.compareToIgnoreCase(Constants.GET_BOOLEAN_IDC_FUNC_NAME) 
  == 0 && schema.getType() == Boolean.class));
 
} catch (UnknownClaimException e) {
return false;
}
} else {
throw new RuntimeException ("Invalid argument number " + argNumber);
 
}
} else {
throw new RuntimeException ("Invalid function name " + functionName);
}
 
}