8 Oracle Fusion Middlewareのアプリケーション・セッション・サービス
Real Application Securityは、アプリケーション・セッションを透過的かつ安全に設定するためのアプリケーション・セッション・サービスをOracle Fusion Middlewareで提供し、既存のアプリケーション・ユーザー、ロール、セキュリティ・コンテキストをサポートします。このアプリケーション・セッション・サービスは、アプリケーション・セッションのセットアップおよびアプリケーションがアプリケーション・セッションで使用できる一連のAPIに使用されるサーブレット・フィルタです。このアプリケーション・セッション・サービスは、Oracle Fusion Middlewareによって外部で管理されるユーザーとロールをサポートします。
Oracle Database 12cリリース1 (12.1.0.2)以降、このアプリケーション・セッション・サービスはOracle Platform Security Service (OPSS)をアプリケーション・セキュリティ・プロバイダとして使用して、Java EE Webアプリケーションをサポートします。このアプリケーション・セッション・サービスは、OPSSでアプリケーションとともにサポートできるJava EEコンテナにデプロイできます。
Real Application Securityの概念について
Real Application SecurityはOracle Database認可システムとして、誰(アプリケーション・ユーザー)がどのデータベース・リソース(マイ・レポート、マイSSNの従業員の購買注文レコード)でどのアプリケーション・レベルの操作(ApprovePurchaseOrder、ViewSSN)を実行できるかを守らせることで、アプリケーションのセキュリティをサポートします。アプリケーション・セッションは、アプリケーション・セキュリティを徹底するために使用されます。一般に、ユーザーとロールは外部でプロビジョニングされます。つまり、エンタープライズ・ユーザーはアイデンティティ・ストアでプロビジョニングされ、アプリケーション・ロールはOracle Identity ManagementやOracle Entitlement Server (OES)などのポリシー・ストアで管理されます。
アプリケーション・ユーザーおよびロールを外部で管理
Real Application Securityは、アプリケーション・ユーザーおよびロールのプロビジョニングを管理するために、Oracle Entitlement Serverなどの外部パーティによってプロビジョニングされたユーザーとロールをサポートします。他方、OPSSはアプリケーション・ロールのセキュリティを徹底するための実行時セキュリティ・フレームワークを提供します。これらは外部アプリケーション・ユーザーおよび外部アプリケーション・ロールと呼ばれます(詳細は、Oracle Fusion MiddlewareとReal Application Securityの統合を参照)。
Real Application Securityには、データベースでネイティブに管理されるアプリケーションのユーザーおよびロールもあり、これらはReal Application Securityアプリケーション・ユーザーおよびアプリケーション・ロールと呼ばれます(詳細は、アプリケーション・ユーザーおよびアプリケーション・ロールの構成を参照)。
外部アプリケーション・ユーザーおよび外部アプリケーション・ロールについては、Real Application Securityはユーザーのロール割当てを含め、ユーザー・プロビジョニングを管理しません。ただし、データベース内のネイティブなアプリケーション・ユーザーおよびアプリケーション・ロールについては、アプリケーション・ユーザーへのアプリケーション・ロールの付与、アプリケーション・ロールへのデータベース・ロールの付与、アプリケーション・ロールへのアプリケーション・ロールの付与がデータベースで管理されます。Real Application Securityアプリケーション・ユーザーとアプリケーション・ロールおよび外部アプリケーション・ユーザーと外部アプリケーション・ロールの両方がアプリケーション・セッションでサポートされ、データ・セキュリティ・ポリシーで使用できます。アイデンティティ・ストアで外部から管理されるユーザーとデータベースでネイティブに管理されるユーザーの両方に、アプリケーション権限を付与できます。
Oracle Fusion Middlewareのアプリケーション・セッション
アプリケーション・セッションはアプリケーション・ユーザーの実行時セキュリティ・コンテキストを表します。これには、ユーザーID、データベースおよびアプリケーション・ロール、ネームスペース属性値が含まれます。Oracle Fusion Middlewareのアプリケーション・セッションは、外部で管理されるユーザーおよびロールを使用しています。アプリケーション・セッションの構成の詳細は、アプリケーション・ユーザー・セッションの構成を参照してください。
Oracle Fusion Middlewareのセッション・マネージャ
Real Application Securityでは、セッション・マネージャがアプリケーション・セッション操作を認可し、アプリケーション・セッションの作成および変更に必要な権限を持っています。アプリケーション・コードまたはアプリケーション・データベース接続は、これらの権限を持つことができません。データベースに対しては、セッション・マネージャはReal Application Security直接ログイン・ユーザーです(直接ログイン・アプリケーション・ユーザー・アカウントの作成を参照)。アプリケーション・セッション・サービスの初期化開始時にデータベースと通信し、認可資格証明に基づいてデータベース・サーバーと信頼関係を構築します。その後、このメカニズムを使用して、アプリケーションの代理でアプリケーション・セッションの操作を引き続き認可します。
Oracle Fusion Middlewareの動的ロール
アプリケーション・ロール以外に、アプリケーション・セッションでは動的ロールをサポートしています。これは、データベースでネイティブに定義する必要があるReal Application Securityロールです(動的アプリケーション・ロールを参照)。このロールは、ユーザーまたは他のロールには付与されません。実行時にアプリケーション・セッションでプログラムによって有効にする必要があります。これはReal Application Securityフィルタで自動的に行うか、信頼できるアプリケーション・コードによって明示的に行います。
動的ロールはリクエスト範囲またはセッション範囲として定義できます。セッション範囲では、次回の連結で無効化するように明示的に指定した場合を除き、有効化された動的ロールは次回の連結でも引き続き有効です。リクエスト範囲では、アプリケーション・セッションが接続から連結解除された後、ロールは無効化されます。
動的ロールには2つの一般的な用途があります。
-
オブジェクト権限
アプリケーション・ユーザーはデータベース・ユーザーではありません。アプリケーション・ユーザーとアプリケーション・ロールが外部アイデンティティ・ストアでプロビジョニングされるときに、これらのオブジェクト権限をReal Application Security動的ロールに付与できます。Real Application Securityフィルタがアプリケーション・ユーザーにアプリケーション・セッションを設定する際、現在のアプリケーションにアクセスしている各アプリケーション・セッションで動的ロールを有効化します。動的ロールは、現在のアプリケーション専用です。
-
アプリケーション・セッション権限の昇格
一部のデータベース操作を実行するために、特定の信頼できるアプリケーション・コードに、一時的に高い権限を付与する必要があります。これをサポートするには、Javaコード・ベース・ポリシーを使用して宣言された信頼できるコードから連結されるアプリケーション・セッション中に、Real Application Security動的ロールを有効にします。連結解除時には、ロールを無効にする必要があります。
ユースケースの1つとして、セッション・ネームスペース属性がReal Application Securityで詳細にセキュリティ保護されている場合のアプリケーション・ネームスペースの設定があげられます。ネームスペースは、データベースでネームスペース・テンプレートとして事前定義しておく必要があります。定義時には、ネームスペースの関連ACLで認可ポリシー、つまり、誰(ユーザー/ロール)がネームスペースで何(modify_namespace、modify_attribute)を実行できるかを指定できます。信頼できるアプリケーション・コードのみがネームスペース属性を変更できるように、動的ロールに権限が付与されます。また、動的ロールは、Javaコード権限で識別される特定の信頼できるアプリケーション・コードによってプログラムを使用してのみ有効化できます。これにより、信頼できるコードのみが特定のネームスペースを設定できるユースケースがサポートされます。
Oracle Fusion Middlewareのアプリケーション・セッション・サービスについて
図8-1は、Oracle Fusion Middlewareに実装されたアプリケーション・セッション・サービスを示しています。
図8-1 Oracle Fusion Middlewareのアプリケーション・セッション・サービス

「図8-1 Oracle Fusion Middlewareのアプリケーション・セッション・サービス」の説明
アプリケーション・セッション・サービスはOracle Fusion Middlewareと統合されたソリューションで、Oracle Fusion Middlewareを活用してデータベースでアプリケーション・セッションを提供します。Oracle Fusion Middlewareでは:
-
アプリケーション・ユーザーは、コンテナによって認証されます。WLSでは一般に、オーセンティケータはSSOサーバーを使用してユーザーを認証します。
-
アプリケーション・ユーザーおよびグループは、アイデンティティ・ストアで管理されます。
-
OPSSは、コンテナのセキュリティ・コンテキストに基づいてアプリケーション・セキュリティ・コンテキストを設定するアプリケーション・セキュリティ・フレームワークです。OPSSを使用したアプリケーション・セキュリティの詳細は、Oracle Application Server Containers for J2EEセキュリティ・ガイドを参照してください。
Real Application Securityサーブレット・フィルタはアプリケーション・セッションを透過的に設定し、アプリケーション・セッションをOPSSサブジェクトと同期します。サーバー・フィルタ・コードは、アプリケーション・セッションで次の働きをする一連のAPIで構成されています。
-
セッションの連結、連結解除、破棄(「アプリケーション・セッションAPIについて」を参照)
-
権限の昇格の提供(「権限昇格APIについて」を参照)
-
ネームスペース操作の提供(「ネームスペースAPIについて」を参照)
-
認可の提供(「権限確認APIについて」を参照)
Real Application Securityは:
-
アプリケーション・セッションで外部ユーザーと外部ロールをサポートするAPIを提供します
-
セッション・マネージャを使用してセッションを認可します
-
ネームスペースでファイングレイン・アクセス・コントロールをサポートします
アプリケーション・セッション・フィルタについて
Real Application Securityアプリケーション・セッション・フィルタは、javax.servlet.Filterインタフェースを実装する標準Java EEサーブレット・フィルタです。このフィルタの基本機能は、認証されたユーザーのセキュリティ・コンテキスト(OPSSサブジェクト)に応じてアプリケーション・セッションを透過的に設定することです。
このアプリケーション・セッション・フィルタを使用することで、アプリケーション・セッションをアプリケーション間で継続的に共有できます。リクエストごとに作成することはできませんが、ステートフル・コンテキストに関連付けて、ログアウトするまで同じユーザーに対して再使用する必要があります。Webアプリケーションの場合、httpセッションがこのようなコンテキストです。ログオンからログアウトまで同じユーザーの継続的なアクセスについて、複数のシングル・サインオン・アプリケーションまたはコンテナ間で、コンテナによって管理されます。
httpセッション・オブジェクトは、ServletFilterからは常にアクセスできますが、汎用アプリケーション・コードからはアクセスできないことがあります。
この項の内容は次のとおりです: アプリケーション・セッション・フィルタ操作について。
アプリケーション・セッション・フィルタ操作について
アプリケーション・セッション・フィルタは、次の方法でアプリケーション・セッションを設定します。
-
ユーザーの初回アクセスで、アプリケーション・セッションを作成します。
ユーザーがログインしている場合は、認証コンテキストのユーザーとしてアプリケーション・セッションを作成します(OPSSサブジェクト)。
ユーザーがログインしていない場合は、匿名ユーザーとしてアプリケーション・セッションを作成します。
-
同じアプリケーションへのユーザーの後続アクセスでは、既存のアプリケーション・セッション・インスタンスを再使用します。
-
複数のアプリケーションが同じReal Application Securityデータベースにアクセスする際、複数のアプリケーション間で同じアプリケーション・セッションを共有します。
-
各httpリクエストの開始時にアプリケーション・セッションを同期して、現在のアプリケーション・セッションのユーザーとロールが常に認証コンテキスト(OPSSサブジェクト)と同期され、各アプリケーション・セッションで構成済の動的ロールのみが有効化されるようにします。
同期は、OPSSサブジェクトの値をサーバーにプッシュし、現在のアプリケーション・セッションについてサーバーで計算された値を取得することによって行われます。
アプリケーション・コードを実行する前にフィルタを起動すると、アプリケーション・セッションのユーザーとロールは固定されます。ユーザーとロールの同期を行うのは、アプリケーション・コードではなくフィルタです。
アプリケーション・コードは、ネームスペースの設定を行います。フィルタは、以前のネームスペースを戻すのに役立つだけです。ネームスペースの設定の詳細は、ネームスペースAPIについてを参照してください。
アプリケーション・セッションは、httpセッションIDに基づいてローカルでキャッシュされます。httpセッションは、コンテナによって管理されます。Real Application Securityには、コンテナのアプリケーション・セッション・イベントをリッスンするためのアプリケーション・セッション・リスナーがあります。コンテナでhttpセッションが無効化されると、アプリケーション・セッションはReal Application Securityリスナーによってローカル・キャッシュから削除されます。
デプロイメントについて
Real Application Securityアプリケーション・セッション・サービスは1つのjarファイル、xsee.jarで配布されます。xsee.jar jarファイルは共通ディレクトリにデプロイすることをお薦めします。Webアプリケーション(web-inf/lib内のWARファイル)と一緒にはデプロイしないでください。この方法により、jarファイルをアプリケーション・コードと分離し、いくつかの特別なコード・ベース権限をアプリケーション・コードには付与せずにxsee.jar jarファイルにのみ付与できます。
xsee.jar jarファイルがCSFストアからセッション・マネージャの資格証明を取得するには、コード・ベース権限CredentialAccessPermissionをxsee.jar jarファイルに付与する必要があります。フィルタは内部的にReal Application Securityセッション・マネージャを使用して、セッション操作を認可します。
例8-1では、xsee.jar jarファイルをWLSのドメイン/libディレクトリにデプロイしています。javaポリシー・ファイル(system-jazn-data.xml)にはCredentialAccessPermission特権があり、セッション・マネージャのキー/マップはデフォルト値を使用していると想定しています。
デプロイ手順については、Oracle WebLogic Serverの理解の標準Java EEデプロイメントに関する項を参照してください。
テストまたは評価を行うためのアプリケーションを簡単にすばやくデプロイするには、自動デプロイメントを使用します。これは、すべて(クラス、web.xml)を1つのWARファイルにパッケージし、Weblogic autodeployディレクトリにコピーすることで、アプリケーション・セッション・サービスを簡単にデプロイする方法です。Oracle WebLogic Serverへのアプリケーションのデプロイの開発ドメインへのアプリケーションの自動デプロイに関する項を参照してください。
セッション・マネージャの資格証明を作成するには、手動構成の手順2を参照してください。
例8-1 xsee.jarファイルへのコード・ベース権限CredentialAccessPermissionの付与
<grant>
<grantee>
<codesource>
<url>file:${domain.home}/lib/xsee.jar</url>
</codesource>
</grantee>
<permissions>
<permission>
<class>oracle.security.jps.service.credstore.CredentialAccessPermission</class>
<name>context=SYSTEM,mapName=oracle.rdbms.ras, keyName=default</name>
<actions>read</actions>
</permission>
</permissions>
</grant>
アプリケーション・セッション・フィルタのアプリケーション構成について
フィルタは、アプリケーションのweb.xml構成ファイルで、標準的な方法で構成されます。特定のURLにのみ適用するように構成できます。これにより、データベース・アクセスを必要としない特定ページに、不必要なアプリケーション・セッションが設定されるのを防ぎます。フィルタは、ユーザー認証が実行され、認証コンテキストが確立されているとみなします。OPSSでは、ユーザーのアプリケーション・コンテキストはOPSSフィルタで計算されるため、フィルタ・チェーンのアプリケーション・セッション・フィルタの前にOPSSフィルタをデプロイする必要があります。アプリケーション・セッション・フィルタは、次のweb.xmlパラメータを使用します。
-
application.datasourceアプリケーションはこの
application.datasourceパラメータを使用します。アプリケーション・セッション・フィルタは、初期化操作、アプリケーション・セッション設定操作およびネームスペース操作にこのパラメータを必要とします。 -
dynamic.roles使用されるReal Application Security動的ロールのリストは、カンマ(,)で区切られます。データベースでセッション範囲として動的ロールが作成されている必要があります。作成されていない場合、次の例外がスローされます:
ORA-46055: 無効なロールが指定されました。このロールは、現在のアプリケーションの各アプリケーション・セッションに対して有効化され、他のアプリケーションでは自動的に無効化されます。これらの動的ロールは、匿名セッションに対して有効化される点に注意してください。各アプリケーション・セッションに不要な場合、動的ロールに過大に権限を付与しないでください。通常、動的ロールに付与する必要があるのはオブジェクト権限のみです。
Real Application Securityによって保護されない表については、アプリケーションはアクセスのために必要に応じてアプリケーション・ユーザーではなくデータベース接続プール・ユーザーを使用できます。その場合、連結アプリケーション・セッションAPIコールは不要であり、動的ロールにオブジェクト権限は付与されません。
-
session.manager.pwd.keyおよびsession.manager.pwd.mapsession.manager.pwd.keyパラメータとsession.manager.pwd.mapパラメータ(oracle.rdbms.rasとして固定)は資格証明ストア内の資格証明(ユーザーIDとパスワード)を指します。session.manager.pwd.keyパラメータは、セッション・マネージャの資格証明を取得するために使用されます。現在、OPSS CSF資格証明ストアは資格証明の格納に使用され、CSF APIは実行時に資格証明を取得するために使用されます。また、セッション・マネージャのユーザーIDとパスワードは両方ともストアから取得できます。session.manager.pwd.keyパラメータのデフォルト値はdefaultです。アプリケーションでデフォルトの資格証明が使用されている場合、このパラメータは省略できます。アプリケーションでデフォルトの資格証明ではなく特定のセッション・マネージャを使用する場合、アプリケーションの管理者は別のキー名で資格証明を作成し、このパラメータを使用して構成する必要があります。詳細は、Oracle Application Server Containers for J2EEセキュリティ・ガイドの「OPSSセキュリティ・ストアの構成」を参照してください。
-
session.manager.pool.minおよびsession.manager.pool.maxセッション・マネージャの接続は、中間層でのデータ・セキュリティ・ポリシー(ACL)の問合せにも使用されます。この接続はプールとして管理されます。
session.manager.pool.minパラメータはプールの最小サイズを決定します。このパラメータはオプションです。デフォルト値は1です。session.manager.pool.maxパラメータはプールの最大サイズを決定します。このパラメータはオプションです。デフォルト値は3です。権限チェックが不要な場合は、
session.manager.pool.min値とsession.manager.pool.max値の両方に対して、プール・サイズを1に設定する必要があります。
例8-2は、サーブレット・フィルタ、そのパラメータ、リスナーを含むアプリケーション・セッション・フィルタのサンプル構成を示しています。デフォルト値のあるパラメータはすべて、この例では省略されています。
例8-2 アプリケーション・セッション・フィルタのサンプル構成
<filter>
<filter-name>ApplicationSessionFilter</filter-name>
<filter-class>oracle.security.xs.ee.session.ApplicationSessionFilter</filter-class>
<init-param>
<param-name>application.datasource</param-name>
<param-value>jdbc/myDBDS</param-value>
</init-param>
<init-param>
<param-name>dynamic.roles</param-name>
<param-value>my_drole</param-value>
</init-param>
</filter>
<listener>
<description>RAS Session Listener</description>
<listener-class>oracle.security.xs.ee.session.ApplicationSessionListener</listener-class>
</listener>
ドメイン構成: OPSSおよびOracle Fusion Middlewareで動作するアプリケーション・セッション・サービスの設定
前提条件
Real Application Securityを使用するには、アプリケーション・セッション・サービスとOPSSの両方をOracle Fusion MiddlewareのJava EEコンテナにデプロイして構成する必要があります。
WebLogic Serverの場合、前提条件は次のとおりです。
-
Oracle database 12c JDBCドライバに対して動作保証されたJRFベースのWLSドメイン(OPSSは組み込まれています)。必要とする機能に応じて、1つのドライバjarだけでなく多数のJDBC jarが必要になることがあります(UCP、I18N、SQLXMLなど)。
-
Oracle Database 12cリリース1 (12.1)以降
WebLogic Server 10.3.6および12.1.2 JRFリリース(Oracle Fusion Middlewareの一部)の場合、付属するJDBCドライバはOracle Database 12c互換ではありません。Oracle Database 12c JDBC jar (ojdbc6.jarまたはojdbc7.jarおよび必要な機能に応じたその他のjar)を取得し、これらのjarをWebLogic Serverのクラスパスの前に追加する必要があります。詳細な手順は、Oracle WebLogic Server JDBCデータ・ソースの管理のセクションBを参照してください。
JDBCドライバとデータベースのバージョンが一致しない場合、Real Application Securityフィルタの初期化はエラー・メッセージが表示されて失敗します。次に例を示します。
-
Oracle Database 11g JDBCドライバがOracle Database 12cで使用されている場合、サーバー・ログに次のエラー・メッセージが表示されます:
メソッドが欠落しているためRASセッション・マネージャを初期化できません。 -
Oracle Database 12c JDBCドライバがOracle Database 11gで使用されている場合、サーバー・ログに次のエラー・メッセージが表示されます:
ORA-00439: 機能は使用できません: Fusionセキュリティ。
手動構成
アプリケーションでアプリケーション・セッション・サービスを使用するには、次の手動構成手順に従います。手順は、WebLogic 10.3.6および12.1.2、JRFリリースの両方に使用できます。
自動構成について
Oracle Fusion Middlewareでは、構成ユーティリティを使用してアプリケーション・グループに共通設定を構成できます。WebLogicの場合、これはドメイン構成ウィザードです。今後のWLSリリース(リリース12.1.3)では、この構成ウィザードによって手順1から3 (手動構成)を自動化できます。この自動アプローチには、オフライン構成をサポートできるという利点もあります(管理サーバーが実行されていない場合)。
構成ウィザードを起動すると(<ORACLE_HOME>/oracle_common/common/bin/config.sh)、次のユーザー・インタフェース(UI)が示され、Real Application Security構成情報の入力を求めるメッセージが表示されます。
-
最初のUIでは、アプリケーション・セッション・サービスは、選択するOracle Fusion Middleware機能の1つとして表示されます。選択すると、その依存関係(OPSS、JRFの一部)も自動的に選択されます。
-
2つめのUIでは、デフォルト・セッション・マネージャの資格証明を入力するよう求められます。
コード権限を付与するUIはありません。これは、事前定義されたxmlファイルをドメインのsystem-jazn-data.xmlファイルに結合することで、自動的に行われます。事前定義されたxmlファイルには、必要なすべてのReal Application Securityコード権限付与が含まれます。
管理者がアプリケーションに別のセッション・マネージャを使用することを決定した場合、管理者は手動による手順2を実行するか、UIから特別なキー名を追加する必要があります。同じキー名をアプリケーションのweb.xmlに渡す必要があります。この場合、マップ名(ストア名)は引き続きoracle.rdbms.rasに固定されているため、コード権限を付与する必要はありません。すべてのキーはすでに内部的に付与されているためです。
アプリケーション・セッションAPIについて
アプリケーション・セッションAPIは、クラスApplicationSessionServiceを介して静的メソッドとして公開されます。APIは、現在のサブジェクトに基づいて設定された現在のアプリケーション・セッションで動作します。各APIの内部では、IDアサーションが内部的に実行され、現在のアプリケーション・セッションがサブジェクトと一致することが確認されます。不一致が見つかった場合、ApplicationSesseionException例外がスローされます。サブジェクトとして呼び指すために、アプリケーション・セッションAPIのコール元コードは、常にSubject.doAsの内部で実行する必要があります。詳細は、JDKのSubject.doAsを参照してください。
アプリケーション・セッションAPIについて
アプリケーション・セッションへの連結について
現在のユーザーのアプリケーション・セッションを、特定のデータベース接続に連結します。
現在のユーザーのアプリケーション・セッションに連結するアプリケーション・コードには、コード・ベース権限は必要ありません。アプリケーション・セッションはそのままで動作し、連結によって追加の権限が昇格されることはありません。
構文
public static void attachSession(java.sql.Connection conn)
throws ApplicationSessionException
パラメータ
| パラメータ | 説明 |
|---|---|
|
|
データベース・サーバー・ラウンドトリップのJDBC接続 |
例
アプリケーション・セッションからの連結解除
現在のユーザーのアプリケーション・セッションを、特定のデータベース接続から連結解除します。
アプリケーション・セッションを常にアプリケーション・コードの最終ブロックから連結解除することをお薦めします。そうしないと、連結された接続が正しいユーザーの下で実行されていないコードに付与されることがあります。使用後にアプリケーション・セッションを適切に連結解除することは、コール元の責任です。
連結解除がコールされずに、同じ接続で連結が再度コールされると、サーバーは前に連結されたアプリケーション・セッションからの連結解除を施行して、現在のアプリケーション・セッションに連結します。
構文
public static void detachSession(java.sql.Connection conn)
throws ApplicationSessionException
パラメータ
| パラメータ | 説明 |
|---|---|
|
|
データベース・サーバー・ラウンドトリップのJDBC接続 |
例
例8-3に、連結および連結解除APIをデータベース問合せとともに使用するサンプル・コードを示します。コール元は、問合せニーズに基づいて、連結コールと連結解除コールの境界を決定する必要があります。
例8-3 アプリケーション・セッションAPI: AttachSessionとDetachSession
/**
* Typical application code calling attach/detach for database query
*/
public void queryHR(Connection conn) {
String query = " select emp.employee_id, emp.salary from hr.employees emp";
Statement stmt = null;
ResultSet rs = null;
String id, salary;
try {
// attach connection to the current application session
ApplicationSessionService.attachSession(conn);
stmt = conn.createStatement();
rs = stmt.executeQuery(query);
while (rs.next()) {
id = rs.getString("employee_id");
salary = rs.getString("salary");
}
} catch (ApplicationSessionException e) {
} catch (SQLException e) {
} finally {
// detach the current application session from the connection
try { ApplicationSessionService.detachSession(conn); } catch (Exception e) {}
if (stmt != null) try {stmt.close();} catch (SQLException e) {};
if (rs != null) try { rs.close();} catch (SQLException e{};
}
}
アプリケーション・セッションの破棄
データベースで現在のアプリケーション・セッションを破棄して、現在のスレッドの実行コンテキストから削除します。これは、ログアウト時にアプリケーションによって呼び出す必要があります。最初にフィルタによって設定された現在のアプリケーション・セッションを破棄します。
構文
public static void destroySession(java.sql.Connection conn)
throws ApplicationSessionException
パラメータ
| パラメータ | 説明 |
|---|---|
|
|
データベース・サーバー・ラウンドトリップのJDBC接続 |
例
例8-4に、アプリケーション・セッション・サービスを破棄するサンプル・コードを示します。
例8-4 アプリケーション・セッションAPI: DestroySession
void doLogout(HttpServletRequest request) {
DataSource dataSource = null;
Connection conn = null;
try {
InitialContext ic;
try {
ic = new InitialContext();
dataSource = (DataSource)ic.lookup("jdbc/myDBDS");
if (dataSource != null)
try {
conn = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
} catch (NamingException e) {
e.printStackTrace();
}
// invalidate Http session
request.getSession().invalidate();
// destroy XS session at DB
ApplicationSessionService.destroySession(conn);
} catch (ApplicationSessionException e) {
e.printStackTrace();
} finally {
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
}
}
}
権限昇格APIについて
この項では、次のトピックについて説明します: アプリケーション・セッションでの動的ロールの有効化。
アプリケーション・セッションでの動的ロールの有効化
現在のアプリケーション・セッションを特定のデータベース接続に連結し、連結したアプリケーション・セッションでReal Application Security動的ロールを有効化します。これにより、アプリケーション・ネームスペースの設定など一部のデータベース操作を実行するために、信頼できるアプリケーション・コードに一時的に高い権限を付与できます。
これは、特定の信頼できるアプリケーション・コードのアプリケーション・セッション権限を昇格するためです。Real Application Security動的ロールは、連結時に有効化されます。信頼できるコードは、javaコード権限によって識別されます。
構文
public static void attachSessionPrivileged(java.sql.Connection conn,
java.lang.String role)
throws ApplicationSessionException
パラメータ
| パラメータ | 説明 |
|---|---|
|
|
データベース・サーバー・ラウンドトリップのJDBC接続 |
|
|
特定の動的ロール、リクエスト範囲である必要があります |
例
使用上の注意
javaセキュリティ・マネージャがオンであるかオフであるか、常にAPIで内部的に権限がチェックされます。コール元に権限がある場合(これは、特定のロールがポリシー・ファイルで定義されたロールとも一致することを意味します)、特定の動的ロールが連結時に有効化されます。権限がない場合、APIはAccessControlExceptionで失敗します。
コール元コード(caller.jarファイル)とアプリケーション・セッション・サービス・コード(xsee.jar)は両方とも、SessioncodePermission権限を持っている必要があります。caller.jarがコンテナによって直接呼び出される場合は、これで十分です。caller.jarが別のアプリケーション・コードによって呼び出される場合、アプリケーション・コードにこの権限が必要かどうかは、コール元が判断します。コール元でアプリケーションにこの権限が必要ない場合、コール元はAccessController.doPrivilegedでnull AccessControllerContextを指定したattachSessionPrivilegedを呼び出すことができます。詳細は、Java APIを参照してください。これを実行することで、caller.jarはアプリケーション・コードを全面的に信頼します。
動的ロールは、現在のアプリケーション・セッションではなく連結されたアプリケーション・セッションでのみ有効化されます。連結および連結解除の期間内で有効化されます。データベースでリクエスト範囲として動的ロールが定義されている必要があります。定義されていない場合、次の例外がスローされます: ORA-46055: 無効なロールが指定されました。
例8-5 権限昇格API
<grant>
<grantee>
<codesource>
<url>file:${domain.home}/servers/DefaultServer/tmp/_WL_user/MyWar/pi47ig/war/WEB-INF/lib/trusted.jar' </url>
</codesource>
</grantee>
<permissions>
<permission>
<class>oracle.security.xs.ee.session.SessionCodePermission</class>
<name> MY_NS_DROLE</name>
<actions>attach </actions>
</permission>
</permissions>
</grant>
<grant>
<grantee>
<codesource>
<url>file:${domain.home}/lib/xsee.jar</url>
</codesource>
</grantee>
<permissions>
<permission>
<class>oracle.security.xs.ee.session.SessionCodePermission</class>
<name>MY_NS_DROLE</name>
<actions>attac </actions>
</permission>
</permissions>
</grant>
ネームスペースAPIについて
ネームスペースの作成について
現在のアプリケーション・セッションでネームスペースを作成します。指定されたネームスペースがデータベースで事前定義されていて、アプリケーション・セッションでADMIN_ANY_NAMESPACE権限が有効化されている場合を除き、連結されたアプリケーション・セッションがMODIFY_NAMESPACE操作を実行することをネームスペースACLで許可する必要があります。
構文
public static void createNamespace(java.sql.Connection conn,
java.lang.String name)
throws ApplicationSessionException
パラメータ
| パラメータ | 説明 |
|---|---|
|
|
データベース・サーバー・ラウンドトリップのJDBC接続 |
|
|
特定のネームスペース名 |
例
例8-6を参照してください。
ネームスペースの削除について
現在のアプリケーション・セッションからネームスペースを削除します。指定されたネームスペースがデータベースで事前定義されていて、アプリケーション・セッションでADMIN_ANY_NAMESPACE権限が有効化されている場合を除き、連結されたアプリケーション・セッションがMODIFY_NAMESPACE操作を実行することをネームスペースACLで許可する必要があります。
構文
public static void deleteNamespace(java.sql.Connection conn,
java.lang.String name)
throws NamespaceNotFoundException,
ApplicationSessionException
パラメータ
| パラメータ | 説明 |
|---|---|
|
|
データベース・サーバー・ラウンドトリップのJDBC接続 |
|
|
特定のネームスペース名。 |
例
例8-6を参照してください。
ネームスペース属性の設定について
属性値を現在のアプリケーション・セッションのネームスペースに設定します。指定されたネームスペースがデータベースで事前定義されていて、アプリケーション・セッションでADMIN_ANY_NAMESPACE権限が有効化されている場合を除き、連結されたアプリケーション・セッションがMODIFY_ATTRIBUTE操作を実行することをネームスペースACLで許可する必要があります。
ネームスペースに属性が存在しない場合、APIは特定の値で属性を作成します。存在する場合は、既存の値を特定の値に設定します。
構文
public static void setNamespaceAttribute(java.sql.Connection conn,
java.lang.String name,
java.lang.String attribute,
java.lang.String value)
throws NamespaceNotFoundException,
ApplicationSessionException
パラメータ
| パラメータ | 説明 |
|---|---|
|
|
データベース・サーバー・ラウンドトリップのJDBC接続 |
|
|
特定のネームスペース名 |
|
|
特定のネームスペース属性名 |
|
|
特定のネームスペース属性値 |
例
例8-6を参照してください。
ネームスペース属性の削除について
現在のアプリケーション・セッションでネームスペースから属性を削除します。指定されたネームスペースがデータベースで事前定義されていて、アプリケーション・セッションでADMIN_ANY_NAMESPACE権限が有効化されている場合を除き、連結されたアプリケーション・セッションがMODIFY_ATTRIBUTE操作を実行することをネームスペースACLで許可する必要があります。
構文
public static void deleteNamespaceAttribute(java.sql.Connection conn,
java.lang.String name,
java.lang.String attribute)
throws NamespaceNotFoundException,
ApplicationSessionException
パラメータ
| パラメータ | 説明 |
|---|---|
|
|
データベース・サーバー・ラウンドトリップのJDBC接続 |
|
|
特定のネームスペース名 |
|
|
特定のネームスペース属性名 |
例
例8-6を参照してください。
ネームスペース属性の取得
現在のアプリケーション・セッションでネームスペースから属性を取得します。特定のネームスペースを作成する必要があります。データベース接続は不要で、この操作に対する権限はチェックされません。
ネームスペースを変更するAPI(getNamespaceAttribute以外)は、入力パラメータとしてデータベース接続を持ちます。これらのAPIは、JVMの現在のアプリケーション・セッションでネームスペースを更新し、変更内容をデータベース表にシリアライズします。接続は連結する必要があります。連結されたアプリケーション・セッションを使用して、サーバーがネームスペースの変更を認可できるかどうかを特定します。
特定の信頼できるアプリケーション・コードにのみ、ネームスペースの設定を許可します。接続は、ネームスペースで昇格権限(MODIFY_NAMESPACE、MODIFY_ATTRIBUTE)を持つ動的ロールで連結できます。これは、attachSessionPrivileged APIを使用し、ネームスペース権限のみを動的ロールに付与することで実現できます。
構文
public static java.lang.String getNamespaceAttribute(java.lang.String name,
java.lang.String attribute)
throws NamespaceNotFoundException,
ApplicationSessionException
パラメータ
| パラメータ | 説明 |
|---|---|
|
|
特定のネームスペース名 |
|
|
特定のネームスペース属性名 |
例
例8-6に、ネームスペースAPIを使用してネームスペースを設定し、アプリケーション・セッションの権限昇格APIを使用するサンプル・サーブレット・フィルタを示します。
アプリケーション・ネームスペースの使用方法について知っておくべき重要な点
次の使用情報で、アプリケーション・ネームスペースの使用方法について重要な点をまとめます。
-
Real Application Securityフィルタは、すべてのアプリケーション・ネームスペースを現在のアプリケーション・セッションにキャッシュします。
-
初回アクセスの場合、データベースに新規アプリケーション・セッションを作成する必要があります。この時点で、まだアプリケーション・ネームスペースは設定されていません。
-
ユーザーの以後のアクセスでは、フィルタが常に、アプリケーション・セッションに作成されたすべてのネームスペースをJVMの現在のアプリケーション・セッションにキャッシュします。
-
-
アプリケーション・コードは常に、現在のアプリケーション・セッションからネームスペースをアクセスします。各更新操作は、表および現在のアプリケーション・セッション(JVM)の値を変更する、サーバーへのラウンド・トリップです。そのために、各更新APIにはデータベース接続パラメータがあります。ただし、読取り属性は、データベースにアクセスせずにJVMの現在のアプリケーション・セッションから読み取るローカル操作です。
-
ネームスペースの変更が正常に完了すると、変更内容は新たに連結されたアプリケーション・セッションだけでなく、すでに連結されたアプリケーション・セッションにも伝播されます。連結されたアプリケーション・セッションはすべて、単一ソース(現在のアプリケーション・セッション)を参照するためです。
-
現在のアプリケーション・セッションのネームスペースは、Webアプリケーションのhttpリクエスト範囲内で同じです。他のアプリケーションはいつでもネームスペースを変更できます。変更は、Real Application Securityフィルタによって現在のhttpリクエストの開始時に1回だけ取得されます。同じhttpリクエスト内で行われた連結はすべて、現在のアプリケーション・セッションの同じネームスペースを参照します。
-
アプリケーション・コードは、ネームスペース値の変更を完全に制御します。現在のアプリケーション・セッションのネームスペースをいつでも読み取り、ネームスペースAPIをコールしてネームスペースを更新するかどうかを決定します。
例8-6 ネームスペースAPI
/**
* Trusted application code (servlet filter) sets up namespace
* Using privilege elevation and namespace APIs
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
Connection conn = null;
try {
conn = myDatasource.getConnection();
// Attach an application session with a dynamic role.
ApplicationSessionService.attachSessionPrivileged(conn, "myNSRole");
try {
// Get the current value.
String currentValue = ApplicationSessionService.getNamespaceAttribute("mySecuredNS", "myAttribute");
// If the current value is not desired, set it.
if ("myValue".compareToIgnoreCase(currentValue) != 0)
ApplicationSessionService.setNamespaceAttribute(conn, "mySecuredNS", "myAttribute", "myValue");
} catch (NamespaceNotFoundException e) {
// Namespace is not found, create it.
ApplicationSessionService.createNamespace(conn, "mySecuredNS");
// Set the attribute.
ApplicationSessionService.setNamespaceAttribute(conn, "mySecuredNS", "myAttribute", "myValue");
}
} catch (SQLException e) {
} catch (ApplicationSessionException e) {
} finally {
// Detach an application session.
try { ApplicationSessionService.detachSession(conn); } catch (Exception e) {}
if (conn != null) try { conn.close();} catch (Exception e) {}
}
// Execution of application code.
chain.doFilter(request, response);
権限チェックAPIについて
この項では、次のトピックについて説明します: ACLの権限のチェック。
ACLの権限のチェック
指定された接続の連結されているアプリケーション・セッションを使用して、ACLの権限をチェックします。次の使用上の注意が伴います。
-
連結された接続が指定されている必要があります。権限チェックは、連結されているアプリケーション・セッションに基づきます。
attachSessionPrivilegedコールを介して、連結されているアプリケーション・セッションに、現在のアプリケーション・セッションより多くの権限を付与できます。 -
APIはACL IDの入力パラメータを取得します。これは、
ORA_GET_ACLID演算子を使用して表から問い合せることができます。この演算子は、現在の行に関連付けられている一連のACL IDを返します。 -
このAPIは、権限名の入力パラメータを取得します。この入力パラメータは、
SELECTまたはUPDATEなどのDML権限か、他のユーザー定義権限です。
構文
public static boolean checkPrivilege(java.sql.Connection conn,
byte[] acls,
java.lang.String privilege)
throws ApplicationSessionException
パラメータ
| パラメータ | 説明 |
|---|---|
|
|
データベース・サーバー・ラウンドトリップのJDBC接続 |
|
|
行形式での特定のACL ID |
|
|
特定の権限名 |
例
例8-7では、行に関連付けられているACLを取得して、ACLのUPDATE権限をチェックします。
例8-7 権限チェックAPI
public Collection<Employee> queryHR(Connection conn ) {
Statement stmt = null;
ResultSet rs = null;
Collection<Employee> result = new ArrayList<Employee>();
try {
// attach session
ApplicationSessionService.attachSession(conn);
stmt = conn.createStatement();
rs = stmt.executeQuery(query);
while (rs.next()) {
Employee emp = new Employee();
emp.setId(rs.getString("EMPLOYEE_ID"));
AuthorizationIndicator ai =
((OracleResultSet)rs).getAuthorizationIndicator("salary");
if (ai == AuthorizationIndicator.NONE) {
emp.setSalary(rs.getString("salary"));
} else {
emp.setSalary("******") ;
}
// get ACL associated with the row
emp.setAcl(rs.getBytes("acl_id"));
// check "update" privilege
boolean canUpdate = ApplicationSessionService.checkPrivilege(conn, emp.getAcl(), "UPDATE");
emp.setUpdate(canUpdate);
result.add(emp);
emp.setFname(rs.getString("first_name"));
emp.setLname(rs.getString("last_name"));
emp.setEmail(rs.getString("email"));
emp.setPhone(rs.getString("phone_number"));
emp.setManagerId(rs.getString("manager_id"));
emp.setDepId(rs.getString("department_id"));
}
} catch (ApplicationSessionException e) {
e.printStackTrace();
// process me
} catch (SQLException e) {
// process me
e.printStackTrace();
} finally {
if (stmt != null) try {stmt.close();} catch (SQLException e) {};
if (rs != null) try { rs.close();} catch (SQLException e) {};
try {ApplicationSessionService.detachSession(conn);} catch (ApplicationSessionException e) {};
}
return result;
}
人事管理デモのユースケース: Javaでの実装
この項では、アプリケーション・セッション・サービスで、Oracle Fusion Middlewareによって外部で管理されるユーザーとロールをサポートする方法を示します。このJava例は、セキュリティ人事管理(HR)シナリオに基づいています。サンプルHRスキーマのEMPLOYEES表を使用します。
関連項目:
ユーザーおよびグループからアプリケーション・ロールへのマッピングの詳細は、HRデモのユースケース - ユーザー・ロールについてを参照してください。
外部プリンシパル用のHRデモ・アプリケーションの設定(setup.sql)
例8-8に、外部プリンシパル用にHRデモ・アプリケーションを設定するセットアップ・スクリプト(setup.sql)を示します。
このセットアップ・スクリプトは、次の操作を実行します。
-
外部ユーザーのオブジェクト権限のための動的ロール
HROBJを作成します。 -
データ権限、更新、削除、挿入を示す、権限
view_sensitive_infoと集約権限update_infoを含むセキュリティ・クラスHRPRIVSを作成します。これは事前定義クラスDMLから生じたクラスです。 -
EMPACL、EMP_ACLを作成し、制限された部門の従業員レコードにアクセスするためのEMP、HRMGRおよびHRREP権限を付与します。各外部プリンシパル(アプリケーション・ロール:HRREP、HRMGRおよびEMP)は、OPSSポリシー・ストアGUID値と一致する必要があります。 -
セルフACL、
SELF_ACLを作成して、従業員に自分のレコードを表示および更新するためのEMP権限を付与します。 -
マネージャACL、
MGR_ACLを作成して、マネージャが自分の従業員の給与情報を確認できるようにします。 -
EMPLOYEES表に、データ・セキュリティ・ポリシーEMPLOYEE_DSを作成します。このポリシーは、部門60および100の従業員へのアクセスを制御するインスタンス・セットをEMP_ACLに定義します。機密性の高いSALARY列へのアクセスを制御する属性制約も定義します。 -
2つの追加インスタンス・セットを
SELF_ACLおよびMGR_ACLに定義し、データ・セキュリティ・ポリシーEMPLOYEE_DSに追加します。 -
ディスパッチャに、追加の権限をいくつか付与します。
例8-8 外部プリンシパル用のHRデモ・アプリケーションの設定
Rem Copyright (c) 2009, 2014, Oracle and/or its affiliates.
Rem All rights reserved.
SET ECHO ON
SET FEEDBACK 1
SET NUMWIDTH 10
SET LINESIZE 80
SET TRIMSPOOL ON
SET TAB OFF
SET PAGESIZE 100
-- A PL/SQL function to determine manager-report relationship
conn hr/hr;
create or replace package hrutil as
function ismyreport(id IN PLS_INTEGER)
return PLS_INTEGER ;
end hrutil;
/
create or replace package body hrutil as
function ismyreport(id IN PLS_INTEGER)
return PLS_INTEGER is
mycount PLS_INTEGER ;
myid PLS_INTEGER ;
begin
select employee_id into myid from hr.employees
where UPPER(email) = XS_SYS_CONTEXT('PROFILE_NS','EMAIL');
select count(employee_id) into mycount from hr.employees
where employee_id = id start with manager_id = myid
connect by prior employee_id = manager_id ;
return mycount ;
end ismyreport ;
end hrutil ;
/
-- Create a dynamic role for object privileges for external users.
connect sys/password as sysdba
show con_name;
-- Create a dynamic role for HR object privileges.
exec xs_principal.delete_principal('HROBJ',XS_ADMIN_UTIL.CASCADE_OPTION);
exec xs_principal.create_dynamic_role('HROBJ');
-- Create a db role to have HR object privileges.
drop role hr_db_obj;
create role hr_db_obj;
-- Grant object privilege to the db role.
grant select, insert, update, delete on hr.employees to hr_db_obj;
-- Grant db role to dynamic role.
grant hr_db_obj to HROBJ;
-- Create a security class with privilege view_sensitive_info, and
-- aggregate privilege update_info that implies data privileges,
-- update, delete, insert, which come from pre-defined security class
-- DML.
DECLARE
priv_list XS$PRIVILEGE_LIST;
BEGIN
priv_list :=XS$PRIVILEGE_LIST(
XS$PRIVILEGE(name=>'VIEW_SENSITIVE_INFO'),
XS$PRIVILEGE(name=>'UPDATE_INFO',
implied_priv_list=>XS$NAME_LIST
('"UPDATE"', '"DELETE"', '"INSERT"')));
xs_security_class.create_security_class(
name=>'HRPRIVS',
parent_list=>XS$NAME_LIST('DML'),
priv_list=>priv_list);
END;
/
-- External Principal (app role) Used for data security:
-- Such a principal must match the OPSS policy store.
-- roleName="HRREP" guid="37ED0D108C2F11E2BF802D569259982"
-- roleName="HRMGR" guid="4077A2B08C2F11E2BF802D569259982"
-- roleName="EMP" guid="F917C3608CF011E2BF802D569259982"
-- Create an EMP Acl to grant EMP, HRMGR and HRREP privileges to access an employee record in the restricted departments.
DECLARE
ace_list XS$ACE_LIST;
BEGIN
ace_list := XS$ACE_LIST(
XS$ACE_TYPE(privilege_list=>XS$NAME_LIST('"SELECT"','VIEW_SENSITIVE_INFO'),
granted=>true,
principal_name=>'"37ED0D108C2F11E2BF802D569259982"', principal_type=>XS_ACL.PTYPE_EXTERNAL),
XS$ACE_TYPE(privilege_list=>XS$NAME_LIST('UPDATE_INFO'),
granted=>true,
principal_name=>'"4077A2B08C2F11E2BF802D569259982"', principal_type=>XS_ACL.PTYPE_EXTERNAL),
XS$ACE_TYPE(privilege_list=>XS$NAME_LIST('"SELECT"'),
granted=>true,
principal_name=>'"F917C3608CF011E2BF802D569259982"', principal_type=>XS_ACL.PTYPE_EXTERNAL));
xs_acl.create_acl(name=> 'EMP_ACL',
ace_list=> ace_list,
sec_class=>'HRPRIVS',
description=> 'Employee access to his/her data');
END;
/
-- Create a self Acl to grant EMP privileges to for an employee to see and update his own record.
-- Grant UPDATE, VIEW_SENSITIVE_INFO privileges to the EMP role.
DECLARE
ace_list XS$ACE_LIST;
BEGIN
ace_list := XS$ACE_LIST(
XS$ACE_TYPE(privilege_list=> XS$NAME_LIST('"UPDATE"', 'VIEW_SENSITIVE_INFO'),
principal_name=>'"F917C3608CF011E2BF802D569259982"', principal_type=>XS_ACL.PTYPE_EXTERNAL));
xs_acl.create_acl(name=> 'SELF_ACL',
ace_list=> ace_list,
sec_class=>'HRPRIVS',
description=> 'Employee access to his/her data');
END;
/
-- Create Manager ACL, to allow a manager to see his employee's salary.
-- Grant VIEW_SENSITIVE_INFO privileges to EMP role on the Manager's employees.
--
DECLARE
ace_list XS$ACE_LIST;
BEGIN
ace_list := XS$ACE_LIST(
XS$ACE_TYPE(privilege_list=> XS$NAME_LIST('VIEW_SENSITIVE_INFO'),
principal_name=>'"F917C3608CF011E2BF802D569259982"', principal_type=>XS_ACL.PTYPE_EXTERNAL));
xs_acl.create_acl(name=> 'MGR_ACL',
ace_list=> ace_list,
sec_class=>'HRPRIVS',
description=> 'Manager can see his reports salaray');
END;
/
-- Create data security policy for the EMPLOYEE table. The policy defines
-- an instant set to control the access to the employees in department
-- 60 and 100. It also defines an attribute constraint to control
-- the access to sensitive column SALARY.
DECLARE
inst_sets XS$REALM_CONSTRAINT_LIST;
attr_secs XS$COLUMN_CONSTRAINT_LIST;
BEGIN
inst_sets :=
XS$REALM_CONSTRAINT_LIST(
XS$REALM_CONSTRAINT_TYPE(realm=> 'DEPARTMENT_ID in (60, 100)',
acl_list=> XS$NAME_LIST('EMP_ACL')));
attr_secs :=
XS$COLUMN_CONSTRAINT_LIST(
XS$COLUMN_CONSTRAINT_TYPE(column_list=> XS$LIST('SALARY'),
privilege=> 'VIEW_SENSITIVE_INFO'));
xs_data_security.create_policy(
name=>'EMPLOYEES_DS',
realm_constraint_list=>inst_sets,
column_constraint_list=>attr_secs);
END;
/
-- Add more instance sets to the above data security.
declare
inst1 xs$REALM_CONSTRAINT_TYPE;
inst2 xs$REALM_CONSTRAINT_TYPE;
begin
inst1 := xs$REALM_CONSTRAINT_TYPE(realm=> 'UPPER(email) = XS_SYS_CONTEXT(''PROFILE_NS'',''EMAIL'')',
acl_list=> XS$NAME_LIST('SELF_ACL'));
xs_data_security.append_realm_constraints('EMPLOYEES_DS', inst1);
inst2 := xs$REALM_CONSTRAINT_TYPE(realm=> 'hr.hrutil.ismyreport(employee_id) = 1',
acl_list=> XS$NAME_LIST('MGR_ACL'));
xs_data_security.append_realm_constraints('EMPLOYEES_DS', inst2);
end;
/
-- Apply the data security policy on the table.
begin
XS_DATA_SECURITY.apply_object_policy(schema=>'HR', object=>'EMPLOYEES',
policy=>'EMPLOYEES_DS');
end;
/
-- Grant more privileges for the dispatcher.
exec XS_ADMIN_UTIL.GRANT_SYSTEM_PRIVILEGE('ADMIN_ANY_NAMESPACE','ts',XS_ADMIN_UTIL.PTYPE_XS);
grant select on sys.dba_xs_session_roles to ts_role;
EXIT;
アプリケーション・セッション・フィルタ構成ファイル(web.xml)について
例8-9に、フィルタ、そのパラメータ、リスナを含む完全なアプリケーション・セッション・フィルタのサンプル構成ファイル(web.xml)を示します。例8-11に示すネームスペース(MyFilter.java)を設定するためのフィルタ、例8-10に示すMyHR.javaという名前のサンプル・サーブレット・アプリケーション、およびMySession.java、MyUpdate.javaおよびLogoutServlet.java(これは示されていません)を参照します。
MySessionはV$XS_SESSION_ROLESビューを問い合せてアプリケーション・セッションのロールを表示し、XS$SESSIONネームスペースのユーザーを問い合せてアプリケーション・セッションのユーザーを表示し、V$XS_SESSION_NS_ATTRIBUTESビューを問い合せてアプリケーション・セッションのネームスペースを表示して、アプリケーション・セッションに連結します。
MyUpdateはHR.EMPLOYEES表で更新を実行して、従業員の電話番号を更新します。
LogoutServletはログアウト操作を実行してから、データベースでアプリケーション・セッションを破棄します。
ApplicationSessionFilterフィルタ構成では、フィルタ・セクションはクラスApllicationSessionFilterを参照し、パラメータapplication.datasourceとパラメータ値jdbc/myDBDSを記述し、パラメータdynamic rolesと例8-8のセットアップ・スクリプトで作成された値HROBJを記述します。
例8-9 完全なアプリケーション・セッション・フィルタのサンプル構成
<?xml version = '1.0' encoding = 'UTF-8'?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5" xmlns="http://java.sun.com/xml/ns/javaee">
<filter>
<filter-name>JpsFilter</filter-name>
<filter-class>oracle.security.jps.ee.http.JpsFilter</filter-class>
<init-param>
<param-name>enable.anonymous</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>remove.anonymous.role</param-name>
<param-value>false</param-value>
</init-param>
<init-param>
<param-name>application.name</param-name>
<param-value>MyHRApp</param-value>
</init-param>
<!-- Following needed for Menu Security -->
<!--init-param>
<param-name>oracle.security.jps.jaas.mode</param-name>
<param-value>subjectOnly</param-value>
</init-param-->
</filter>
<filter>
<filter-name>ApplicationSessionFilter</filter-name>
<filter-class>oracle.security.xs.ee.session.ApplicationSessionFilter</filter-class>
<init-param>
<param-name>application.datasource</param-name>
<param-value>jdbc/myDBDS</param-value>
</init-param>
<init-param>
<param-name>dynamic.roles</param-name>
<param-value>HROBJ</param-value>
</init-param>
<!--
<init-param>
<param-name>dispatcher.pool.max</param-name>
<param-value>90</param-value>
</init-param>
-->
<!-- init-param>
<param-name>application.id</param-name>
<param-value>MyHRApp</param-value>
</init-param>
<init-param>
<param-name>session.provider</param-name>
<param-value>XS</param-value>
</init-param>
<init-param>
<param-name>db.url</param-name>
<param-value>jdbc:oracle:thin:@myhost:1521:orcl</param-value>
</init-param>
<init-param>
<param-name>dispatcher.id</param-name>
<param-value>ts</param-value>
</init-param>
<init-param>
<param-name>dispatcher.pwd.map</param-name>
<param-value>XS_MAP</param-value>
</init-param>
<init-param>
<param-name>dispatcher.pwd.key</param-name>
<param-value>XS_KEY</param-value>
</init-param>
<init-param>
<param-name>dispatcher.pool.min</param-name>
<param-value>3</param-value>
</init-param>
<init-param>
<param-name>dispatcher.pool.max</param-name>
<param-value>10</param-value>
</init-param -->
<!--init-param>
<param-name>namespaces</param-name>
<param-value>sec_ns</param-value>
</init-param-->
</filter>
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>trusted.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>JpsFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>ApplicationSessionFilter</filter-name>
<url-pattern>/myhr</url-pattern>
<url-pattern>/mysession</url-pattern>
<url-pattern>/myupdate</url-pattern>
<url-pattern>/logout</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/myhr</url-pattern>
<url-pattern>/mysession</url-pattern>
<url-pattern>/myupdate</url-pattern>
<dispatcher>FORWARD</dispatcher>
<dispatcher>REQUEST</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<listener>
<listener-class>oracle.security.xs.ee.session.ApplicationSessionListener</listener-class>
</listener>
<servlet>
<servlet-name>MySession</servlet-name>
<servlet-class>app.MySession</servlet-class>
</servlet>
<servlet>
<servlet-name>LogoutServlet</servlet-name>
<servlet-class>app.MyLogout</servlet-class>
</servlet>
<servlet>
<servlet-name>MyHR</servlet-name>
<servlet-class>app.MyHR</servlet-class>
</servlet>
<servlet>
<servlet-name>MyUpdate</servlet-name>
<servlet-class>app.MyUpdate</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MySession</servlet-name>
<url-pattern>/mysession</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>LogoutServlet</servlet-name>
<url-pattern>/logout</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MyHR</servlet-name>
<url-pattern>/myhr</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MyUpdate</servlet-name>
<url-pattern>/myupdate</url-pattern>
</servlet-mapping>
<security-constraint>
<web-resource-collection>
<web-resource-name>my servlet</web-resource-name>
<url-pattern>/myhr</url-pattern>
<url-pattern>/mysession</url-pattern>
<url-pattern>/myupdate</url-pattern>
</web-resource-collection>
<auth-constraint>
<role-name>valid-users</role-name>
</auth-constraint>
</security-constraint>
<login-config>
<auth-method>CLIENT-CERT,FORM</auth-method>
<form-login-config>
<form-login-page>/login.jsp</form-login-page>
<form-error-page>/error.jsp</form-error-page>
</form-login-config>
</login-config>
<security-role>
<role-name>valid-users</role-name>
</security-role>
</web-app>
サンプル・サーブレット・アプリケーション(MyHR.java)について
例8-10に、例8-9に示すアプリケーション・セッション・フィルタのサンプル構成(web.xmlファイル)で参照されている、MyHR.javaというサンプル・サーブレット・アプリケーションを示します。
MyHRアプリケーションはEMPLOYEES表で問合せを実行して、結果を返します。権限がある場合は、ログイン資格証明に応じて、次に説明されている特定タスクを実行できます。
-
従業員として、自分の給与情報は表示できますが、他人の給与情報は表示できず、自分の連絡先情報のみ更新できます。
-
HRマネージャとしてログインしている場合、すべての従業員の給与レコードを表示でき、彼らの連絡先情報を更新できます。
-
HRデモ(3) - チーム・マネージャとしてログインについて
チーム・マネージャとしてログインしている場合、自分のチームの従業員の給与情報のみ表示できますが、彼らの連絡先情報は更新できず、自分の連絡先情報のみ更新できます。
ACLの権限チェック(checkPrivilege)から、UPDATE権限がある場合はその従業員のレコードの更新を実行する権限があり、EMPLOYEE_IDにその従業員のレコードにアクセスできるリンクが表示されます。
例8-10 サンプル・サーブレット・アプリケーション(MyHR.java)
/* Copyright (c) 2009, 2014, Oracle and/or its affiliates.
All rights reserved.*/
package app;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import oracle.jdbc.OracleResultSet;
import oracle.jdbc.OracleResultSet.AuthorizationIndicator;
import oracle.security.xs.ee.session.ApplicationSessionException;
import oracle.security.xs.ee.session.ApplicationSessionService;
public class MyHR extends HttpServlet {
private static final String CONTENT_TYPE = "text/html; charset=UTF-8";
String query = " select emp.EMPLOYEE_ID, emp.first_name, emp.last_name, " +
" emp.email, emp.phone_number, salary, emp.manager_id, " +
" emp.department_id,ora_get_aclids(emp) as acl_id" +
" from hr.employees emp";
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
public void queryHR(PrintWriter out) throws ApplicationSessionException {
DataSource dataSource = null;
Connection conn = null;
try {
InitialContext ic;
try {
ic = new InitialContext();
dataSource = (DataSource)ic.lookup("jdbc/myDBDS");
if (dataSource != null)
try {
conn = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
} catch (NamingException e) {
e.printStackTrace();
}
try {
queryHR(conn, out);
} catch (Exception e) {
e.printStackTrace();
}
} finally {
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
}
}
}
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException {
response.setContentType(CONTENT_TYPE);
PrintWriter pw = response.getWriter();
pw.println(HEADER);
pw.println("<h1><font size=\"+2\">RAS Session Service Demo</font></h1>");
pw.println("<font size=\"+1\">");
pw.println("You are logged in as <b>" + request.getRemoteUser() + "</b>");
try {
queryHR(pw);
} catch (ApplicationSessionException e) {
e.printStackTrace();
}
pw.println(FOOTER);
pw.close();
}
public Collection<Employee> queryHR(Connection conn ) {
Statement stmt = null;
ResultSet rs = null;
Collection<Employee> result = new ArrayList<Employee>();
try {
// attach session
ApplicationSessionService.attachSession(conn);
stmt = conn.createStatement();
rs = stmt.executeQuery(query);
while (rs.next()) {
Employee emp = new Employee();
emp.setId(rs.getString("EMPLOYEE_ID"));
AuthorizationIndicator ai =
((OracleResultSet)rs).getAuthorizationIndicator("salary");
if (ai == AuthorizationIndicator.NONE) {
emp.setSalary(rs.getString("salary"));
} else {
emp.setSalary("******") ;
}
// get ACL associated with the row
emp.setAcl(rs.getBytes("acl_id"));
// check "update" privilege
boolean canUpdate = ApplicationSessionService.checkPrivilege(conn, emp.getAcl(), "UPDATE");
emp.setUpdate(canUpdate);
result.add(emp);
emp.setFname(rs.getString("first_name"));
emp.setLname(rs.getString("last_name"));
emp.setEmail(rs.getString("email"));
emp.setPhone(rs.getString("phone_number"));
emp.setManagerId(rs.getString("manager_id"));
emp.setDepId(rs.getString("department_id"));
}
} catch (ApplicationSessionException e) {
e.printStackTrace();
// process me
} catch (SQLException e) {
// process me
e.printStackTrace();
} finally {
if (stmt != null) try {stmt.close();} catch (SQLException e) {};
if (rs != null) try { rs.close();} catch (SQLException e) {};
try {ApplicationSessionService.detachSession(conn);} catch (ApplicationSessionException e) {};
}
return result;
}
public void queryHR(Connection conn, PrintWriter out ) {
Collection<Employee> list = queryHR(conn);
PrintWriter pw = out;
pw.println("<br>Displaying employee record(s) that you can access.<br>");
pw.println("</font>");
pw.println("<i>NOTE: Salary is only shown if you are authorized to view,
and ID is shown as a link if you are authorized to perform an update.</i><br>");
out.println("<table border=\"1\">");
String tmp;
if (list.size() > 0) {
out.println("<tr>");
out.println("<th>ID</th>");
out.println("<th>First Name</th>");
out.println("<th>Last Name</th>");
out.println("<th>Email</th>");
out.println("<th>Phone</th>");
out.println("<th>Salary</th>");
out.println("<th>Department ID</th>");
out.println("<th>Manager ID</th>");
out.println("</tr>");
}
for (Employee e: list) {
if (e.canUpdate()) {
tmp = "<a href=\"update.jsp?id=" + e.getId() + "\">" + e.getId() + "</a>";
} else {
tmp = e.getId();
}
out.println("<tr><td>" + tmp + "</td>");
out.println("<td>" + e.getFname() + "</td>");
out.println("<td>" + e.getLname() + "</td>");
out.println("<td>" + e.getEmail() + "</td>");
out.println("<td>" + e.getPhone() + "</td>");
out.println("<td>" + e.getSalary() + "</td>");
out.println("<td>" + e.getDepId() + "</td>");
out.println("<td>" + e.getManagerId() + "</td></tr>");
}
out.println("</TABLE>");
};
class Employee {
String id;
String salary;
boolean update;
String fname;
String lname;
String email;
String phone;
String managerId;
String depId;
byte[] acl;
public void setId(String id) {
this.id = id;
}
public String getId() {
return id;
}
public void setSalary(String salary) {
this.salary = salary;
}
public String getSalary() {
return salary;
}
public void setUpdate(boolean canUpdate) {
this.update = canUpdate;
}
public boolean canUpdate() {
return update;
}
public void setFname(String fname) {
this.fname = fname;
}
public String getFname() {
return fname;
}
public void setLname(String lname) {
this.lname = lname;
}
public String getLname() {
return lname;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPhone() {
return phone;
}
public void setManagerId(String managerId) {
this.managerId = managerId;
}
public String getManagerId() {
return managerId;
}
public void setDepId(String depId) {
this.depId = depId;
}
public String getDepId() {
return depId;
}
public void setAcl(byte[] acl) {
this.acl = acl;
}
public byte[] getAcl() {
return acl;
}
}
private static String HEADER = "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head>"
+ "<meta content=\"text/html; charset=UTF-8\" http-equiv=\"content-type\"/>"
+ "<title>Oracle</title>"
+ "<link href=\"css/general.css\" type=\"text/css\" rel=\"stylesheet\"/>"
+ "<link href=\"css/window.css\" type=\"text/css\" rel=\"stylesheet\"/>"
+ "<link href=\"css/login.css\" type=\"text/css\" rel=\"stylesheet\"/>"
+ "<script type=\"text/javascript\">"
+ " if (top != self) top.location.href = location.href;"
+ "</script>"
+ "<style type=\"text/css\">"
+ "html { background-color: #001C34;}"
+ "</style>"
+ "</head>"
+ "<body onload=\"document.loginData.j_username.focus();\">"
+ " <div id=\"top\">"
+ " <div id=\"login-header\">"
+ " <div id=\"login-logo\">"
+ " <img src=\"images/logo.png\"/>"
+ "</div>"
+ " </div>"
+ " <div id=\"content\">"
+ "<div id=\"app_data\"><div id=\"title\"></div>";
private static String FOOTER = "<a href=\"/myapp/logout\">Logout</a>"
+ "</div></div><div id=\"info\"></div></div></body></html>";
}
アプリケーション・ネームスペースを設定するためのフィルタ(MyFilter.java)について
例8-11に、アプリケーション・ネームスペースを設定するためのフィルタを示します。このフィルタはMyHR.javaという名前で、例8-9に示すアプリケーション・セッション・フィルタのサンプル構成(web.xmlファイル)で参照されています。
このフィルタは別個のjarとしてデプロイする必要があり、jarファイルにSessionCodePermissionを付与する必要があります。
このフィルタはまずV$XS_SESSION_ROLESビューを問い合せて、Real Security Applicationセッションのロールを表示します。次に、このフィルタは信頼できるアプリケーション・コード(フィルタ)がネームスペース(getNamespaceAttribute)が存在するかどうかを最初にチェックする方法をデモし、存在しない場合は、セッション権限昇格(attachSessionPrivileged)を使用してセキュリティ・クリティカルなネームスペースおよびネームスペースAPI (createNamespace、setNamespaceAttribute)を設定してネームスペースを作成し、ネームスペース属性を設定します。
例8-11 アプリケーション・ネームスペースを設定するためのフィルタ
/* Copyright (c) 2009, 2014, Oracle and/or its affiliates.
All rights reserved.*/
package trusted;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.sql.DataSource;
import oracle.security.xs.ee.session.ApplicationSessionException;
import oracle.security.xs.ee.session.ApplicationSessionService;
import oracle.security.xs.ee.session.NamespaceNotFoundException;
/**
* Demonstrate how trusted application code (a filter) can set up
* security critical namespace using session privilege elevation and
* namespace APIs.
*
* The filter should be deployed as a separate jar, and SessionCodePermission
* should be granted to the jar.
*/
public class MyFilter implements Filter {
private FilterConfig _filterConfig = null;
DataSource myDatasource = null;
public void init(FilterConfig filterConfig) throws ServletException {
_filterConfig = filterConfig;
}
public void destroy() {
_filterConfig = null;
}
public void querySessionRoles(Connection conn) throws SQLException {
String query =
"select role_name from v$xs_session_roles order by role_name";
String roles = null;
try {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
System.out.println("<p> roles in RAS session (from myfilter):</p>");
System.out.println("<TABLE>");
while (rs.next()) {
roles = rs.getString(1);
System.out.println("<tr><td>" + roles + "</td></tr>");
}
System.out.println("</TABLE>");
} finally {
}
return;
}
private boolean namespaceExists(String ns, String attribute, String value) throws ApplicationSessionException {
try {
return value.equalsIgnoreCase(ApplicationSessionService.getNamespaceAttribute(ns, attribute));
} catch (NamespaceNotFoundException e) {
return false;
}
}
private Connection getConnection() {
DataSource dataSource = null;
InitialContext ic;
try {
ic = new InitialContext(); //TODO cache context
dataSource = (DataSource)ic.lookup("jdbc/myDBDS");
if (dataSource != null)
try {
return dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
} catch (NamingException e) {
e.printStackTrace();
}
return null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) {
Connection conn = null;
try {
String email = ((HttpServletRequest)request).getRemoteUser();
if ( email != null && !namespaceExists("PROFILE_NS", "EMAIL", email )) {
conn = getConnection();
//AccessController.doPrivileged(new AttachAction(conn), null);
ApplicationSessionService.attachSessionPrivileged(conn, "SESSION_NS_DROLE");
ApplicationSessionService.createNamespace(conn, "PROFILE_NS");
ApplicationSessionService.setNamespaceAttribute(conn, "PROFILE_NS", "EMAIL", email);
ApplicationSessionService.detachSession(conn);
}
} catch (ApplicationSessionException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null)
try {
conn.close();
} catch (SQLException e) {
}
}
try {
chain.doFilter(request, response);
} catch (IOException e) {
e.printStackTrace();
} catch (ServletException e) {
e.printStackTrace();
}
}
}
HRデモのユースケース - ユーザー・ロールについて
HRデモのユースケースでは、アイデンティティ管理ストアにユーザー名、ユーザー名のパスワード、グループ名が含まれます。他方、OPSSセキュリティ・ストアにはアプリケーション・ロールとユーザーおよびグループからアプリケーション・ロールへのマッピングが含まれます。例8-12に、あるユーザーLPOPPについて、ユーザーおよびグループからアプリケーション・ロールへのマッピングを行うためのコード・スニペットを示します。
例8-12 ユーザーおよびグループからアプリケーション・ロールへのマッピング
<app-role>
<name>EMP</name>
<display-name>Employee for dept #60 and dept #100</display-name>
<description>HR manager for dept #60 and representative for dept #100</description>
<guid>F917C3608CF011E2BF802D569259982</guid>
<class>oracle.security.jps.service.policystore.ApplicationRole</class>
<members>
<member>
<class>weblogic.security.principal.WLSUserImpl</class>
<name>LPOPP</name>
</member>
</members>
</app-role>
HRデモ(1) - 従業員LPOPPとしてログインについて
表8-1に、従業員LPOPPとしてログインした場合にアクセスできる従業員レコードを示します。全員の給与情報以外のレコードおよび自分の給与情報を表示でき、自分の連絡先情報を更新できます。
このアクセス権は、次によって設定されます。
-
レルムおよび権限付与(1):
DEPARTMENT_ID in (60, 100)およびSELECT to EMP -
レルムおよび権限付与(2):
UPPER(email) = XS_SYS_CONTEXT("PROFILE_NS","EMAIL")およびUPDATE, VIEW_SENSITIVE_INFO to EMP -
列制約:
SALARYにはVIEW_SENSITIVE_INFO権限が必要です
給与は、ユーザーに表示権限がある場合にのみ表示され、更新権限がある場合はリンクとしてIDが示されます(表にイタリック形式で)。
例8-1 セッション・サービスHRデモ(1) - 従業員LPOPPとしてログイン
| ID | 名 | 姓 | 電子メール | 電話番号 | 給与 | 部門ID | マネージャID |
|---|---|---|---|---|---|---|---|
|
103 |
Alexander |
Hunold |
AHUNOLD |
510.222.3388 |
****** |
60 |
102 |
|
104 |
Bruce |
Ernst |
BERNST |
590.423.4568 |
****** |
60 |
103 |
|
105 |
David |
Austin |
DAUSTIN |
590.423.4569 |
****** |
60 |
103 |
|
106 |
Valli |
Pataballa |
VPATABAL |
590.423.4560 |
****** |
60 |
103 |
|
107 |
Diana |
Lorentz |
DLORENTZ |
590.423.4567 |
****** |
60 |
103 |
|
108 |
Nancy |
Greenberg |
NGREENBE |
515.124.4569 |
****** |
100 |
101 |
|
109 |
Daniel |
Faviet |
DFAVIET |
515.124.4169 |
****** |
100 |
108 |
|
110 |
John |
Chen |
JCHEN |
515.124.4269 |
****** |
100 |
108 |
|
111 |
Ismael |
Sciarra |
ISCIARRA |
515.124.4369 |
****** |
100 |
108 |
|
112 |
Jose Manuel |
Urman |
JMURMAN |
515.124.4469 |
****** |
100 |
108 |
|
113 |
Luis |
Popp |
LPOOP |
133.444.5555 |
6900 |
100 |
108 |
HRデモ(2) - HRMGRとしてログインについて
表8-2に、HRマネージャHRMGRとしてログインした場合にアクセスできる従業員レコードを示します。すべての従業員の給与情報を表示でき、すべての従業員の連絡先情報を更新できます。
このアクセス権は、次のレルムおよび権限付与によって設定されます: DEPARTMENT_ID in (60, 100)、SELECT、UPDATEおよびVIEW_SENSITIVE_INFO to HRMGR。
給与は、ユーザーに表示権限がある場合にのみ表示され、更新権限がある場合はリンクとしてIDが示されます(表にイタリック形式で)。
例8-2 セッション・サービスHRデモ(2) - HRマネージャHRMGRとしてログイン
| ID | 名 | 姓 | 電子メール | 電話番号 | 給与 | 部門ID | マネージャID |
|---|---|---|---|---|---|---|---|
|
103 |
Alexander |
Hunold |
AHUNOLD |
510.222.3388 |
9000 |
60 |
102 |
|
104 |
Bruce |
Ernst |
BERNST |
590.423.4568 |
6000 |
60 |
103 |
|
105 |
David |
Austin |
DAUSTIN |
590.423.4569 |
4800 |
60 |
103 |
|
106 |
Valli |
Pataballa |
VPATABAL |
590.423.4560 |
4800 |
60 |
103 |
|
107 |
Diana |
Lorentz |
DLORENTZ |
590.423.4567 |
4200 |
60 |
103 |
|
108 |
Nancy |
Greenberg |
NGREENBE |
515.124.4569 |
12008 |
100 |
101 |
|
109 |
Daniel |
Faviet |
DFAVIET |
515.124.4169 |
9000 |
100 |
108 |
|
110 |
John |
Chen |
JCHEN |
515.124.4269 |
8200 |
100 |
108 |
|
111 |
Ismael |
Sciarra |
ISCIARRA |
515.124.4369 |
7700 |
100 |
108 |
|
112 |
Jose Manuel |
Urman |
JMURMAN |
515.124.4469 |
7800 |
100 |
108 |
|
113 |
Luis |
Popp |
LPOOP |
133.444.5555 |
6900 |
100 |
108 |
HRデモ(3) - チーム・マネージャとしてログインについて
表8-3に、チーム・マネージャAHUNOLDとしてログインした場合にアクセスできる従業員レコードを示します。チーム・マネージャの給与情報は表示できますが、彼らの連絡先情報は更新できず、自分の連絡先情報のみ更新できます。
このアクセス権は、次のレルムおよび権限付与によって設定されます: is my member(employee_id) =1とVIEW_SENSITIVE_INFO to EMP。
給与は、ユーザーに表示権限がある場合にのみ表示され、更新権限がある場合はリンクとしてIDが示されます(表にイタリック形式で)。
例8-3 セッション・サービスHRデモ(3) - チーム・マネージャAHUNOLDとしてログイン
| ID | 名 | 姓 | 電子メール | 電話番号 | 給与 | 部門ID | マネージャID |
|---|---|---|---|---|---|---|---|
|
103 |
Alexander |
Hunold |
AHUNOLD |
510.222.3388 |
9000 |
60 |
102 |
|
104 |
Bruce |
Ernst |
BERNST |
590.423.4568 |
6000 |
60 |
103 |
|
105 |
David |
Austin |
DAUSTIN |
590.423.4569 |
4800 |
60 |
103 |
|
106 |
Valli |
Pataballa |
VPATABAL |
590.423.4560 |
4800 |
60 |
103 |
|
107 |
Diana |
Lorentz |
DLORENTZ |
590.423.4567 |
4200 |
60 |
103 |
|
108 |
Nancy |
Greenberg |
NGREENBE |
515.124.4569 |
****** |
100 |
101 |
|
109 |
Daniel |
Faviet |
DFAVIET |
515.124.4169 |
****** |
100 |
108 |
|
110 |
John |
Chen |
JCHEN |
515.124.4269 |
****** |
100 |
108 |
|
111 |
Ismael |
Sciarra |
ISCIARRA |
515.124.4369 |
****** |
100 |
108 |
|
112 |
Jose Manuel |
Urman |
JMURMAN |
515.124.4469 |
****** |
100 |
108 |
|
113 |
Luis |
Popp |
LPOOP |
133.444.5555 |
****** |
100 |
108 |