Real Application Securityは仮想プライベート・データベースの後継となる機能です。軽量のアプリケーション・セッションを導入し、そのセッションに紐づくユーザー(アプリケーション・ユーザー)およびロール(アプリケーション・ロール)を定義します。これらの定義を元に、データを保護します。
実際に仮想プライベート・データベースで構成した保護を、Real Application Securityで行っていきます。
ユーザーRASADMINの作成
Real Application Securityを構成するユーザーRASADMINを作成します。データベース・アクションにユーザーADMINで接続し、管理のデータベース・ユーザーを開きます。ユーザーの作成をクリックします。
ユーザー名をRASADMINとしパスワードを設定、WebアクセスをONにします。ユーザーの作成をクリックします。
ユーザーRASADMINが作成されます。
開発のSQL開いて、ユーザーRASADMINに必要な権限を与えます。Autonomous DatabaseではプロシージャXS_ADMIN_CLOUD_UTIL.GRANT_SYSTEM_PRIVILEGEを呼び出します。ポリシーやACLの構成する権限ADMIN_ANY_SEC_POLICYと、ユーザーやロールを構成する権限PROVISIONを与えます。パッケージXS_ADMIN_CLOUD_UTILはAutonomous Database向けに準備されているパッケージであり、オンプレミスではXS_ADMIN_UTILパッケージがその機能を提供しています。
APEXアプリケーションでは、仮想プライベート・データベースによる保護と同様に表AUTH_USERSを使用してユーザー認証を行います。そのために表AUTH_USERSを誰からでもアクセスできるようにします。
ユーザー認証に使用する表を誰でもアクセス可能にする、といった実装は普通は行いません。今回の作業例ではReal Application Securityを外部ユーザーとして認証するよう実装します。この場合、ユーザーは外部サービスであるディレクトリ・サービス等で定義されていることを前提としますが、外部サービスの代わりに表AUTH_USERSを使用しているため誰でも検索できるようにしています。
ユーザーRASADMINの作成は完了です。データベース・アクションからサインアウトします。
認証スキームの構成
ユーザーRASADMINでサインインし、認証スキーム内で指定するアプリケーション・ロールとネームスペース・テンプレートの作成を行います。
アプリケーション・ロールEMPLOYEEを作成します。Real Application Securityのユーザーを外部ユーザーとして構成するため(アプリケーション・ユーザーはデータベースに作成されない)、ロールを事前にユーザーに割り当てることはできません。そのためロールは動的ロールとして作成します。
動的ロールの作成にはプロシージャXS_PRINCIPAL.CREATE_DYNAMIC_ROLEを呼び出します。作成した動的ロールにロールHR_ROLEを割り当ることにより、スキーマHRにある表EMP、DEPTへのアクセス権限を与えます。
作成した動的ロールはビューDBA_XS_DYNAMIC_ROLES、動的ロールに与えられたロールはビューDBA_XS_ROLE_GRANTSより確認できます。
続いて、ネームスペース・テンプレートHREMPを作成します。仮想プライベート・データベースでのアプリケーション・コンテキストと同じ用途で使用します。サインインしたユーザーの従業員番号EMPNOをempno、部門番号DEPTNOをdeptnoとして保持します。アプリケーション・コンテキストはファンクションSYS_CONTEXTを通して値を参照することに対して、RASのネームスペースではファンクションXS_SYS_CONTEXTが使われます。
ネームスペースの作成にはプロシージャXS_NAMESPACE.CREATE_TEMPLATEを呼び出します。
認証スキームの動作確認を行います。アプリケーションを実行し、ユーザーSCOTTにてサインインしてみます。
APEXアプリケーションからサインインしたセッションに、Real Application Securityのアプリケーション・ユーザーとロールが割り当たるようになりました。このユーザーとロールによるデータの保護を構成します。
最初にセキュリティ・クラスemp_privを作成します。プロシージャXS_SECURITY_CLASS.CREATE_SECURITY_CLASSを呼び出します。parent_listとしてsys.dmlを指定することで、標準で定義されている権限のリスト("SELECT","UPDATE","INSERT","DELETE")を引き継いでいます。セキュリティ・クラスemp_privが持つ特別な権限はview_salで、これは列SALとCOMMへのアクセスを制御します。
2つのACL、emp_aclとmgr_aclを作成します。プロシージャXS_ACL.CREATE_ACLを呼び出します。emp_aclはサインインしたユーザーと同じ部門の従業員にアクセスを限定するために使用します。mgr_aclはサインインしたユーザーがマネージャーである従業員の列SALとCOMMにアクセスを限定するために使用します。
Real Application Security側での準備ができたので、APEXアプリケーションの認証スキームを変更します。アプリケーションの共有コンポーネントより、認証スキーム従業員による認証を開き、Real Application SecurityのRASモードを外部ユーザーに変更します。動的ロールEMPLOYEEおよびネームスペースのHREMPをシャトルの右側に移し、有効にします。
認証スキームのソースに、認証後に実行するプロシージャとして、ネームスペースHREMPを初期化するpostauthを追加します。追加するコードは以下になります。
ソースのPL/SQLコードにすでに記載されているファンクションauth_employees_onlyに続けて記述します。
ログイン・プロセスの認証後のプロシージャ名にpostauthを指定します。変更の適用をクリックします。
アプリケーション定義属性のセキュリティを開きます。認可のロールまたはグループ・スキームのソースを認証スキームに変更します。RASモードの動的ロールを有効にする、必須の設定です。
仮想プライベート・データベースの構成で使用していた、データベース・セッションの初期化PL/SQLコードとPL/SQLコードのクリーンアップのプロシージャを削除し、変更の適用をクリックします。
以上で認証スキームがRASモードに変更されました。RASモードは外部ユーザーなので、RASのユーザーの作成は不要です。
エラーが発生せず正常にサインインできれば、Real Application Securityは有効になっています。
Real Application Securityによる保護の設定
データベース・アクションにユーザーRASADMINで接続します。開発のSQLを開きます。
最初にセキュリティ・クラスemp_privを作成します。プロシージャXS_SECURITY_CLASS.CREATE_SECURITY_CLASSを呼び出します。parent_listとしてsys.dmlを指定することで、標準で定義されている権限のリスト("SELECT","UPDATE","INSERT","DELETE")を引き継いでいます。セキュリティ・クラスemp_privが持つ特別な権限はview_salで、これは列SALとCOMMへのアクセスを制御します。
作成されたセキュリティ・クラスはビューUSER_XS_SECURITY_CLASSESより確認できます。
作成したACLは、セキュリティ・クラスemp_privへ紐付けます。また、アクセス制御エントリ(ACE)のprincipal_nameとして動的ロールemployeeを指定しています。そのため、動的ロールEMPLOYEEを持っているセッションで、これらのACLで保護されているアクセスが許可されます。
データ・セキュリティ・ポリシーemployees_dsを作成します。プロシージャXS_DATA_SECURITY.CREATE_POLICYを呼び出します。
ACLのemp_aclを適用するrealmの設定として、deptno = xs_sys_content('HREMP','deptno')を指定します。結果として、サインインした従業員と同じ部門の従業員の情報にアクセスが制限されます。また、mgr_aclのrealmはmgr = xs_sys_content('HREMP','empno')とします。結果として、サインインした従業員がマネージャーである従業員にアクセスが制限されます。
作成したデータ・セキュリティ・ポリシーemployees_dsを表HR.EMPに適用します。プロシージャXS_DATA_SECURITY.APPLY_OBJECT_POLICYを呼び出します。
設定を検証するために、プロシージャXS_DIAG.VALIDATE_WORKSPACEを呼び出します。All Configurations are correct.と表示されると、設定に問題はありません。
SCOTT' or '1' = '1
仮想プライベート・データベースによる保護と同様に、サインインしたユーザーSCOTTと同じ部門の従業員の一覧に制限されています。
作成されたACLはビューUSER_XS_ACLSより確認できます。ACLに紐づいているACEはビューUSER_XS_ACESより確認できます。
ACLのemp_aclを適用するrealmの設定として、deptno = xs_sys_content('HREMP','deptno')を指定します。結果として、サインインした従業員と同じ部門の従業員の情報にアクセスが制限されます。また、mgr_aclのrealmはmgr = xs_sys_content('HREMP','empno')とします。結果として、サインインした従業員がマネージャーである従業員にアクセスが制限されます。
作成されたデータ・セキュリティ・ポリシーはビューUSER_XS_POLICIES、セキュリティ・ポリシーに含まれるレルムの構成はUSER_XS_REALM_CONSTRAINTS、USER_XS_COLUMN_CONSTRAINTS等から確認できます。
以上でReal Application Securityによる表HR.EMPの保護ができました。適用されたデータ・セキュリティ・ポリシーはビューALL_XS_APPLIED_POLICIESより確認できます。
以上でReal Application Securityによる表HR.EMPの保護は完了です。
動作確認
テスト用アプリケーションを実行し、今までに設定したReal Application Securityによる保護を確認します。
従業員名に以下を指定します。
SCOTT' or '1' = '1
仮想プライベート・データベースによる保護と同様に、サインインしたユーザーSCOTTと同じ部門の従業員の一覧に制限されています。
従業員名に以下を指定します。
SCOTT' UNION SELECT EMPNO, ENAME || ' - ' || SAL || ' - ' || COMM ENAME, JOB, MGR, HIREDATE, DEPTNO FROM HR.EMP WHERE '1'='1
列EnameにSALの情報が表示されますが、サインインしたユーザーSCOTTがマネージャーである従業員に限定されています。
以上で作業は完了です。
Real Application Securityによって保護されたままだと、後続の作業に支障があるため、保護の設定を削除します。